JavaScript 數(shù)組方法總結(jié)

Array.prototype.pop()

pop() 方法從數(shù)組中刪除最后一個(gè)元素并返回該元素。此方法更改數(shù)組的長(zhǎng)度。

const plants = ['broccoli', 'cauliflower', 'cabbage', 'kale', 'tomato'];

plants.pop() // "tomato"
console.log(plants) // ["broccoli", "cauliflower", "cabbage", "kale"]
plants.pop()
console.log(plants) // ["broccoli", "cauliflower", "cabbage"]

對(duì)空數(shù)組使用 pop 方法,不會(huì)報(bào)錯(cuò),而是返回undefined

[].pop() // undefined

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.push()

push() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的末尾,并返回?cái)?shù)組的新長(zhǎng)度。

const animals = ['pigs', 'goats', 'sheep']

animals.push('cows') //  4
console.log(animals) // ["pigs", "goats", "sheep", "cows"]
animals.push('chickens') // 5
console.log(animals) //  ["pigs", "goats", "sheep", "cows", "chickens"]

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.shift()

shift() 方法從數(shù)組中刪除第一個(gè)元素并返回該元素。此方法更改數(shù)組的長(zhǎng)度。

const arr = [1, 2, 3]
const firstElement = arr.shift()

console.log(arr) //  [2, 3]
console.log(firstElement) // 1

遍歷并清空一個(gè)數(shù)組

const arr = [1, 2, 3]
let item

while (item = list.shift()) {
  console.log(item)
}

list // []

上面代碼通過 list.shift() 方法每次取出一個(gè)元素,從而遍歷數(shù)組。它的前提是數(shù)組元素不能是 0 或任何布爾值等于 false 的元素,因此這樣的遍歷不是很可靠。

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.unshift()

unshift() 方法將一個(gè)或多個(gè)元素添加到數(shù)組的開頭,并返回?cái)?shù)組的新長(zhǎng)度。

const arr = [1, 2, 3]

console.log(arr.unshift(4, 5)) //  5
console.log(arr) // [4, 5, 1, 2, 3]

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.join()

join() 方法以指定參數(shù)作為分隔符,將數(shù)組的所有元素連接為一個(gè)字符串返回。如果不提供參數(shù),默認(rèn)用逗號(hào)分隔。

const arr = ['Fire', 'Air', 'Water']

console.log(arr.join()) // "Fire,Air,Water"
console.log(arr.join(' ')) // "Fire Air Water"
console.log(arr.join('-')) // "Fire-Air-Water"

如果數(shù)組成員是 undefinednull 或空位,會(huì)被轉(zhuǎn)成空字符串。

[undefined, null].join('#') // '#'

['a',, 'b'].join('-') // 'a--b'

通過 call 方法,join 方法也可以用于字符串或類數(shù)組的對(duì)象。

Array.prototype.join.call('hello', '-') // "h-e-l-l-o"

const obj = { 0: 'a', 1: 'b', length: 2 }
Array.prototype.join.call(obj, '-') // 'a-b'

示例:重復(fù)字符串

使用 join 方法來重復(fù)字符串。

Array(4).join('LOVE') // 'LOVELOVELOVE'

Array.prototype.concat()

concat() 方法用于合并兩個(gè)或多個(gè)數(shù)組。此方法不會(huì)更改現(xiàn)有數(shù)組,而是返回一個(gè)新數(shù)組。

const arr1 = ['a', 'b', 'c']
const arr2 = ['d', 'e', 'f']

console.log(arr1.concat(arr2)) // ["a", "b", "c", "d", "e", "f"]

除了數(shù)組作為參數(shù),concat也接受其他類型的值作為參數(shù),添加到目標(biāo)數(shù)組尾部。

const arr = []

arr.concat(1, '1', true, {}, null, undefined) // [1, '1', true, {…}, null, undefined]

如果數(shù)組成員包括對(duì)象,concat 方法返回當(dāng)前數(shù)組的一個(gè)淺拷貝。所謂“淺拷貝”,指的是新數(shù)組拷貝的是對(duì)象的引用。

Array.prototype.isArray()

isArray() 方法確定傳遞的值是否為數(shù)組。

Array.isArray([1, 2, 3])  // true
Array.isArray({ foo: 123 }) // false
Array.isArray('foobar')   // false
Array.isArray(undefined)  // false

Array.prototype.reverse()

reverse() 反轉(zhuǎn)數(shù)組的元素順序。第一個(gè)數(shù)組元素變?yōu)樽詈笠粋€(gè),最后一個(gè)數(shù)組元素變?yōu)榈谝粋€(gè)。

const arr = ['one', 'two', 'three']
console.log(arr) // ['one', 'two', 'three']

const reversed = arr.reverse()
console.log(reversed) // ['three', 'two', 'one']
console.log(arr) // ['three', 'two', 'one']

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.slice()

slice() 方法選取數(shù)組的一部分,并返回一個(gè)新數(shù)組。原始數(shù)組不會(huì)被修改。

const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']

console.log(animals.slice(2)) // ["camel", "duck", "elephant"]
console.log(animals.slice(2, 4)) // ["camel", "duck"]
console.log(animals.slice(1, 5)) // ["bison", "camel", "duck", "elephant"]

如果 slice 方法的參數(shù)是負(fù)數(shù),則表示倒數(shù)計(jì)算的位置。

animals.slice(-2) // ['duck', 'elephant']
animals.slice(-2, -1) // ['duck']

slice 方法的一個(gè)重要應(yīng)用,是將類數(shù)組的對(duì)象轉(zhuǎn)為真正的數(shù)組。

Array.prototype.slice.call({ 0: "a", 1: "b", length: 2 }) // ['a', 'b']

Array.prototype.splice()

splice() 方法通過刪除現(xiàn)有元素或添加新元素來更改數(shù)組的內(nèi)容。

const months = ['Jan', 'March', 'April', 'June']
months.splice(1, 0, 'Feb')

// 在第 1 個(gè)索引位置插入
console.log(months) // ['Jan', 'Feb', 'March', 'April', 'June']

// 在第 4 個(gè)索引處替換 1 個(gè)元素
months.splice(4, 1, 'May')
console.log(months) // ['Jan', 'Feb', 'March', 'April', 'May']

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.indexOf()

indexOf() 方法返回?cái)?shù)組中可以找到給定元素的第一個(gè)索引,如果該元素不存在,則返回 -1。

const beasts = ['ant', 'bison', 'camel', 'duck', 'bison']

console.log(beasts.indexOf('bison')) // 1

// 從索引 2 開始
console.log(beasts.indexOf('bison', 2)) // 4
console.log(beasts.indexOf('giraffe')) // -1

Array.prototype.lastIndexOf()

lastIndexOf() 方法返回?cái)?shù)組中可以找到給定元素的最后一個(gè)索引,如果該元素不存在,則返回 -1。從 fromIndex 開始向后搜索數(shù)組。

const animals = ['Dodo', 'Tiger', 'Penguin', 'Dodo']

console.log(animals.lastIndexOf('Dodo')) // 3

console.log(animals.lastIndexOf('Tiger')) // 1

Array.prototype.includes()

includes() 是 ES7 新增的數(shù)組方法,用于判斷數(shù)組是否包含某個(gè)元素,并根據(jù)條件返回 truefalse。

const arr = [10, 11, 3, 20, 5]

const includesTwenty = arr.includes(20)
console.log(includesTwenty) // true

includes 方法還接受一個(gè)可選參數(shù),根據(jù)索引來指定要從數(shù)組中的哪個(gè)位置開始搜索。默認(rèn)情況下,index 參數(shù)為零。

const arr = [1, 2, 3, 4, 5]

if(arr.includes(3, 2)) {
  console.log('item found')
} else {
  console.log('item not found')
}

建議:使用 includes 替代 indexOf 檢查數(shù)組是否包含某個(gè)元素。

Array.prototype.reduce()

reduce() 方法根據(jù) reducer 函數(shù)和初始值創(chuàng)建任何類型的輸出值。根據(jù)提供的 reducer 函數(shù),結(jié)果可以是任何類型,例如整數(shù)、對(duì)象或數(shù)組。

const arr = [1, 2, 3, 4]
const reducer = (acc, cur) => acc + cur

console.log(arr.reduce(reducer)) // 10
console.log(arr.reduce(reducer, 5)) // 15

通過 reducer 函數(shù)僅獲取 name 鍵:

const input = [
  { 'name' : 'O.O', 'age': 18 },
  { 'name' : 'D.O', 'age': 18 },
  { 'name' : 'K.O', 'age': 18 },
  { 'name' : 'O.K', 'age': 18 }
]

const reducer = (acc, cur) => {
  acc.push({ 'name': cur.name })
  return acc
}

let output = input.reduce(reducer, [])
console.log(output)

注意:Reduce() 支持所以現(xiàn)代瀏覽器,以及 IE9 及更高版本,如果想支持低版本瀏覽器,可以添加一個(gè) polyfill 以支持 IE6。

Array.prototype.reduceRight()

reduceRight() 方法對(duì)累加器應(yīng)用一個(gè)回調(diào)函數(shù),數(shù)組的每個(gè)值(從右到左)都必須將其減少為單個(gè)值。

const arr = [[0, 1], [2, 3], [4, 5]].reduceRight(
  (acc, cur) => acc.concat(cur)
)

console.log(arr) // [4, 5, 2, 3, 0, 1]

Array.prototype.filter()

filter() 方法使用一個(gè)過濾函數(shù)創(chuàng)建一個(gè)新數(shù)組,只保留基于該函數(shù)返回 true 的元素。結(jié)果是一個(gè)長(zhǎng)度等于或小于原始數(shù)組長(zhǎng)度的數(shù)組,包含與原始數(shù)組相同元素的子集。

const array = [10, 11, 3, 20, 5]
const greaterThanTen = array.filter(item => item > 10)
console.log(greaterThanTen) //[11, 20]

示例:過濾對(duì)象數(shù)組

const countries = [
  { name: 'Nigeria', continent: 'Africa' },
  { name: 'Nepal', continent: 'Asia' },
  { name: 'Angola', continent: 'Africa' },
  { name: 'Greece', continent: 'Europe' },
  { name: 'Kenya', continent: 'Africa' },
  { name: 'Greece', continent: 'Europe' }
]

let asianCountries = countries.filter(country => country.continent === 'Asia')

console.log(asianCountries); // [{name: "Nepal", continent: "Asia"}]

示例:在數(shù)組中搜索特定字母

const names = ['Victoria', 'Pearl', 'Olivia', 'Annabel', 'Sandra', 'Sarah']
const filterItems = letters => names.filter(name => name.includes(letters))

console.log(filterItems('ia')) // ["Victoria", "Olivia"]

Array.prototype.map()

map() 方法將提供的函數(shù)應(yīng)用于數(shù)組的每個(gè)元素并返回一個(gè)新數(shù)組。

const arr = [1, 2, 3]
const double = x => x * 2
arr.map(double) // [2, 4, 6]

Array.prototype.flat()

flat 方法創(chuàng)建一個(gè)新數(shù)組,其中所有子數(shù)組元素遞歸連接到該數(shù)組中,直到指定的深度。

const arr1 = [1, 2, [3, 4]]
arr1.flat() // [1, 2, 3, 4]

const arr2 = [1, 2, [3, 4, [5, 6]]]
arr2.flat() // [1, 2, 3, 4, [5, 6]]

const arr3 = [1, 2, [3, 4, [5, 6]]]
arr3.flat(2) // [1, 2, 3, 4, 5, 6]

const arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]]
arr4.flat(Infinity) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

更多實(shí)現(xiàn)技巧可查閱數(shù)組扁平化

Array.prototype.flatMap()

flatMap() 方法首先使用 map 方法映射每個(gè)元素,然后將結(jié)果壓縮成一個(gè)新數(shù)組。它與 map 連著深度值為 1 的 flat 幾乎相同,但 flatMap 通常在合并成一種方法的效率稍微高一些。

const arr = [1, 2, 3, 4]

arr.flatMap(x => [x * 2]) // [2, 4, 6, 8]

// 只有一層是扁平的
arr.flatMap(x => [[x * 2]]) // [[2], [4], [6], [8]]

Array.prototype.sort()

sort() 方法對(duì)數(shù)組中的元素進(jìn)行適當(dāng)排序并返回?cái)?shù)組。這種情況不一定穩(wěn)定。默認(rèn)排序順序根據(jù)字符串 Unicode 代碼點(diǎn)。

const months = ['March', 'Jan', 'Feb', 'Dec']
months.sort() // ['Dec', 'Feb', 'Jan', 'March']
console.log(months) // ["Dec", "Feb", "Jan", "March"]

const arr = [1, 30, 4, 21, 100000]
arr.sort()
console.log(arr) // [1, 100000, 21, 30, 4]

我們可以向 sort 方法傳入一個(gè)指定按某種順序進(jìn)行排列的函數(shù)。

arr.sort((a, b) => a - b) // [1, 4, 21, 30, 100000]
arr.sort((a, b) => b - a) // [100000, 30, 21, 4, 1]

更多內(nèi)容可查閱如何在 JavaScript 中對(duì)對(duì)象數(shù)組進(jìn)行排序?

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.every()

every() 方法對(duì)數(shù)組中每一項(xiàng)運(yùn)行給定函數(shù),如果函數(shù)對(duì)每一項(xiàng)都返回 true,則返回 true。

const arr = [1, 2, 3, 4, 5]

const isBelowThreshold = currentValue => currentValue < 10
console.log(arr.every(isBelowThreshold)) // true

Array.prototype.some()

some() 方法對(duì)數(shù)組中每一項(xiàng)運(yùn)行給定函數(shù),如果函數(shù)對(duì)任一項(xiàng)返回 true,則返回 true。

const arr = [1, 2, 3, 4, 5]

// 檢查元素是否為偶數(shù)
const even = item => item % 2 === 0
console.log(arr.some(even)) // true

示例:數(shù)組扁平化

let arr = [1, 2, [3, 4, 5, [6, 7], 8], 9, 10, [11, [12, 13]]]

const flatten = function (arr) {
  // 只要有一個(gè)元素為數(shù)組,那么循環(huán)繼續(xù)
  while (arr.some(Array.isArray)) {
    arr = [].concat(...arr)
  }
  return arr
}

console.log(flatten(arr))

Array.prototype.forEach()

forEach() 方法對(duì)每個(gè)數(shù)組元素執(zhí)行一次提供的回調(diào)函數(shù)。

const arr = ['a', 'b', 'c']

arr.forEach(item => console.log(item))

// "a"
// "b"
// "c"

Array.prototype.find()

find() 方法返回匹配器函數(shù)為其返回 true 的第一個(gè)元素。否則返回 -1。其結(jié)果是原始數(shù)組中的一個(gè)元素。

const arr = [10, 11, 3, 20, 5]

const greaterThanTen = arr.find(item => item > 10)
console.log(greaterThanTen) // 11

Array.prototype.findIndex()

findIndex() 方法返回?cái)?shù)組中滿足提供的測(cè)試函數(shù)的第一個(gè)元素的索引。否則返回 -1。

const arr = [5, 12, 8, 130, 44]

const isLargeNumber = item => item > 13
console.log(arr.findIndex(isLargeNumber)) // 3

Array.prototype.findLast/findLastIndex

通過 findfindIndex 在數(shù)組中查找值是一種常見的做法。不過,這些方法從數(shù)組開頭開始迭代。

const things = [{v: 1}, {v: 2}, {v: 3}, {v: 4}, {v: 5}]

things.find(item => item.v > 3) // {v: 4}
things.findIndex(item => item.v > 3) // 3

如果您想從數(shù)組的末尾開始搜索數(shù)組,則必須反轉(zhuǎn)數(shù)組并使用提供的方法。這并不好,因?yàn)樗枰槐匾臄?shù)組突變。

幸運(yùn)的是,有一個(gè)針對(duì) findLastfindLastIndex 的 ECMAscript 提案。

const things = [{v: 1}, {v: 2}, {v: 3}, {v: 4}, {v: 5}]

things.findLast(item => item.v > 3) // {v: 5}
things.findLastIndex(item => item.v > 3) // 4

該提案目前處于第三階段,目前已經(jīng) Edge、chromium 和 Safari 的最新版本得到支持。至于其余的,core-js 和 Babel 已經(jīng)提供了一個(gè) polyfill。

以下是 findLast 的支持情況,findLastIndex 與其相同:

findLast 的支持情況

Array.prototype.toLocaleString()

toLocaleString() 返回一個(gè)字符串表示數(shù)組中的元素。數(shù)組中的元素將使用各自的 toLocaleString 方法轉(zhuǎn)成字符串,這些字符串將使用一個(gè)特定語(yǔ)言環(huán)境的字符串(例如一個(gè)逗號(hào) ",")隔開。

const arr = [1, 'a', new Date('21 Dec 1997 14:12:00 UTC')]
const localeString = arr.toLocaleString('en', { timeZone: 'UTC' })

console.log(localeString) // "1,a,12/21/1997, 2:12:00 PM"
// 這假設(shè) 'en' 語(yǔ)言環(huán)境和 UTC 時(shí)區(qū) - 您的結(jié)果可能會(huì)有所不同

Array.prototype.keys()

keys() 方法返回一個(gè)新的數(shù)組可迭代對(duì)象,包含原始數(shù)組中每個(gè)索引的鍵。

const arr = ['a', 'b', 'c']
  
for (let key of arr.keys()) {
  console.log(key) // 0 1 2
}

Array.prototype.values()

values() 方法返回一個(gè)新的數(shù)組迭代器對(duì)象,該對(duì)象包含數(shù)組中每個(gè)索引的值。

const arr = ['a', 'b', 'c']

for (const value of arr.values()) {
  console.log(value) // "a" "b" "c"
}

Array.prototype.entries()

entries() 方法返回一個(gè)新的數(shù)組可迭代對(duì)象,該對(duì)象包含數(shù)組中每個(gè)索引的鍵/值對(duì)。

const arr = ['a', 'b', 'c']
const iterator = arr.entries()

console.log(iterator.next().value) // [0, "a"]

console.log(iterator.next().value) // [1, "b"]

Array.prototype.fill()

fill() 方法使用一個(gè)固定值來填充從起始索引(默認(rèn) 0)到結(jié)束索引(默認(rèn) array.length)的數(shù)組的所有元素。它返回修改后的數(shù)組。

const arr = [1, 2, 3, 4]

// 從位置 2 到位置 4 填充 0
console.log(arr.fill(0, 2, 4)) // [1, 2, 0, 0]

// 從位置 1 填充 5
console.log(arr.fill(5, 1)) // [1, 5, 5, 5]

console.log(arr.fill(6)) // [6, 6, 6, 6]

Array(3) // [empty × 3]
const money = () => '??' 
[...Array(3)].map(money) // ['??', '??', '??']
Array(3).fill('??') // ['??', '??', '??']

示例:重復(fù)字符串

Array(3)
  .fill('LOVE')
  .join('')

// "LOVELOVELOVE"

該片段的運(yùn)行很簡(jiǎn)單:Array(3) 創(chuàng)建一個(gè)包含 3 個(gè)空項(xiàng)的新數(shù)組,fill('LOVE') 在每個(gè)空項(xiàng)中填充 LOVE,join() 將所有元素連接成一個(gè)字符串。

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.copyWithin()

copyWithin() 方法將數(shù)組的一部分復(fù)制到同一數(shù)組中的另一個(gè)位置并返回它,而不修改其大小。

const arr = ['a', 'b', 'c', 'd', 'e']

// 將索引 3 處的元素復(fù)制到索引 0
console.log(arr.copyWithin(0, 3, 4)) // ["d", "b", "c", "d", "e"]

// 將從索引 3 到末尾的所有元素復(fù)制到索引 1
console.log(arr.copyWithin(1, 3)) // ["d", "d", "e", "d", "e"]

注意:該方法會(huì)改變?cè)瓟?shù)組。

Array.prototype.of()

Array.of() 方法從數(shù)量可變的參數(shù)創(chuàng)建一個(gè)新的數(shù)組實(shí)例,而不管參數(shù)的數(shù)量或類型如何。

Array.of(7) // [7]
Array(7) // [empty × 7],7個(gè)空插槽的數(shù)組

Array.of(1, 2, 3) // [1, 2, 3]
Array(1, 2, 3)    // [1, 2, 3]

Array.of() 和數(shù)組構(gòu)造函數(shù)之間的區(qū)別在于處理整數(shù)參數(shù):Array.of(7) 創(chuàng)建一個(gè)包含單個(gè)元素 7 的數(shù)組,而 Array(7) 創(chuàng)建一個(gè)長(zhǎng)度屬性為 7 的空數(shù)組(注意:這意味著數(shù)組包含 7 個(gè)空插槽,而不是包含實(shí)際未定義值的插槽)。

Array.prototype.from()

Array.from() 用于將類數(shù)組對(duì)象或可迭代對(duì)象轉(zhuǎn)化為一個(gè)新的淺拷貝數(shù)組實(shí)例。

console.log(Array.from('foo')) // ["f", "o", "o"]
console.log(Array.from([1, 2, 3], x => x + x)) // [2, 4, 6]

Array.from() 接受第二個(gè) map 參數(shù)。方便創(chuàng)建和填充特定長(zhǎng)度的數(shù)組。

使用 Array.from 填充特定長(zhǎng)度

ES6 Set是可以相互轉(zhuǎn)換的,可以使用 Array.from 轉(zhuǎn)換成數(shù)組

const article = new Set(['JavaScript', 'TypeScript', 'Node.js'])

article // Set(3) {'JavaScript', 'TypeScript', 'Node.js'}
Array.from(article) // ['JavaScript', 'TypeScript', 'Node.js']

示例:重復(fù)字符串

一個(gè)類數(shù)組對(duì)象必須含有 length 屬性,且元素屬性名必須是數(shù)值或者可轉(zhuǎn)換為數(shù)值的字符。我們正好可以利用這一點(diǎn)。

我們將 length 屬性設(shè)置為 3,使用 from() 方法初始化數(shù)組,每個(gè)位置對(duì)應(yīng) 1 個(gè) undefined。 如下:

Array.from({ length: 3 }) // [undefined, undefined, undefined]

現(xiàn)在我們使用第二個(gè)參數(shù),這是一個(gè) map 函數(shù),它將調(diào)用數(shù)組的每個(gè)元素。在這里,我們用 'LOVE' 替換所有的 undefined。

Array.from({ length: 3 }, () => 'LOVE') // ['LOVE', 'LOVE', 'LOVE']

最后我們調(diào)用 join() 方法將數(shù)組中的所有元素組合成一個(gè)字符串。

Array.from({ length: 3 }, () => 'LOVE').join('') //'LOVELOVELOVE'

分塊

在使用 API 時(shí),我經(jīng)常需要將用戶列表分塊并批量發(fā)送。Array.from() 是一種將數(shù)組分塊的好方法,因?yàn)榈诙€(gè)參數(shù)是一個(gè) map 函數(shù)。

function chunkify(array, chunkSize = 10) {
  const chunks = Array.from(
    { length: Math.ceil(array.length / 10) },
    (_, i) => {
      const start = chunkSize * i
      return array.slice(start, start + chunkSize)
    }
  )
  return chunks
}

chunkify(hugeArray) // [[...], [...], ....]

Array.prototype.toString()

toString() 方法返回一個(gè)字符串,表示指定的數(shù)組及其元素。

const arr = [1, 2, 'a', 'b']
console.log(arr.toString()) // "1,2,a,b"

const arr = [1, 2, 3, [4, 5, 6]]
console.log(arr.toString()) // "1,2,3,4,5,6"

Array.prototype.valueOf()

valueOf() 方法返回指定對(duì)象的原始值。

不同對(duì)象的 valueOf 方法不盡一致,數(shù)組的 valueOf 方法返回?cái)?shù)組本身。

const arr = [1, 2, 3]
arr.valueOf() // [1, 2, 3]

詳細(xì)查看 MDN 上valueOf 各個(gè)類型的示例。

有無(wú) mutation

mutation 譯為突變,可以簡(jiǎn)單理解為是否改變?cè)瓟?shù)組,有無(wú)副作用。

mutation:

  • splice()copyWithin()、fill()pop()、push()
  • reverse()shift()、sort()、unshift()

no mutation:

  • some()map()、forEach()、every()、filter()reduce()、reduceRight()
  • find()findIndex()、lastIndexOf()includes()、indexOf()、findLast()、findLastIndex()
  • join()slice()、concat()、flat()flatMap()、of()、from()
  • toLocaleString()toSource()、toString()、valueOf()、keys()、values()、entries()

根據(jù)特定條件搜索

上面已經(jīng)介紹了數(shù)組的所有方法,我們可以使用一些數(shù)組方法來代替 for 循環(huán)來搜索數(shù)組。根據(jù)需要,您可以決定哪種方法最適合您的用例。

  • 如果要查找數(shù)組中滿足特定條件的所有項(xiàng),請(qǐng)使用 filter
  • 如果要檢查至少一項(xiàng)是否滿足特定條件,請(qǐng)使用 find
  • 如果要檢查數(shù)組是否包含特定值,請(qǐng)使用 includes。
  • 如果要查找數(shù)組中特定項(xiàng)的索引,請(qǐng)使用 indexOf
  • 如果要檢查數(shù)組中所有元素是否滿足給定條件,并且返回一個(gè)布爾值,請(qǐng)使用 every。
  • 如果要檢查數(shù)組中任一元素是否滿足給定條件,并且返回一個(gè)布爾值,請(qǐng)使用 some

concat 和 push 的區(qū)別

concatpush 是將一個(gè)或多個(gè)項(xiàng)附加到給定數(shù)組的常用方法。

區(qū)別

concat 方法不會(huì)更改現(xiàn)有數(shù)組:

const shapes = ['Triangle', 'Square']

shapes.concat(['Circle', 'Rectangle']) // ['Triangle', 'Square', 'Circle', 'Rectangle']
shapes // ['Triangle', 'Square']

另一方面,push 方法會(huì)修改原始數(shù)組。

const animals = ['cat', 'dog', 'mouse']
animals.push('bird', 'cow') // 5
animals // ['cat', 'dog', 'mouse', 'bird', 'cow']

在上面的示例代碼中,兩種方法產(chǎn)生不同的結(jié)果。concat 返回一個(gè)新數(shù)組,push 返回更新數(shù)組的長(zhǎng)度。

因?yàn)?concat 創(chuàng)建了一個(gè)新數(shù)組來保存合并數(shù)組的結(jié)果,所以它比 push 慢。

對(duì)于小型數(shù)組,這兩種方法在性能方面不會(huì)產(chǎn)生顯著差異。但是如果你必須使用大數(shù)組,性能是應(yīng)用程序的關(guān)鍵,那么考慮使用 push。

提示

您可以使用 ES6 擴(kuò)展運(yùn)算符將不同的數(shù)組合并為一個(gè):

const a = [1, 2, 3]
const b = [4, 5, 6]
const c = [7, 8, 9]

const final = [...a, ...b, ...c] // [1, 2, 3, 4, 5, 6, 7, 8, 9]

如果我們也使用 push 方法,則擴(kuò)展運(yùn)算符很方便:

const a = [1, 2, 3]
const b = [4, 5, 6]

a.push(...b) // 6
a // [1, 2, 3, 4, 5, 6]

Array.prototype.push.apply(firstArray, secondArray) 是另一個(gè)同樣適用于 ES5 的選項(xiàng)。但是,如果第二個(gè)數(shù)組非常大,則不建議使用這種方法,因?yàn)橐粋€(gè)函數(shù)中的最大參數(shù)數(shù)是有限的。

Array.prototype.push.apply(a, b) // 6
a // [1, 2, 3, 4, 5, 6]

如果你好奇的話,它的硬編碼是 65536。

Javascript Array.push is 945x faster than Array.concat ???? 提供了許多基準(zhǔn)來證明為什么 pushconcat 更快。

slicesplice 的區(qū)別

slicesplice 是獲取給定數(shù)組子數(shù)組的常用方法。

區(qū)別

語(yǔ)法:

array.slice(startingIndex, endingIndex)
array.splice(startingIndex, length, ...items)

雖然第一個(gè)參數(shù)彼此相同,表示刪除元素的起始索引,但第二個(gè)參數(shù)不同。

slicesplice 的第二個(gè)參數(shù)分別是結(jié)束索引和子項(xiàng)數(shù)。

splice 更改原始數(shù)組,而 slice 不更改。

給定從 1 到 5 的數(shù)字?jǐn)?shù)組:

const arr = [1, 2, 3, 4, 5]
const sub = arr.splice(2, 3)

// 原始數(shù)組已修改
arr // [1, 2]
sub // [3, 4, 5]

現(xiàn)在,讓我們將相同的參數(shù)傳遞給 slice

const arr = [1, 2, 3, 4, 5]
const sub = arr.slice(2, 3)

// 原始數(shù)組未被修改
arr // [1, 2, 3, 4, 5]
sub // [3]

使用 splice 方法,可以通過將項(xiàng)目傳遞到最后一個(gè)參數(shù)來保持項(xiàng)目不從原始數(shù)組中移除。

const arr = [1, 2, 3, 4, 5]
const sub = arr.splice(2, 3, 3, 4, 5)

arr // [1, 2, 3, 4, 5]

提示

我們可以通過忽略結(jié)束索引來克隆數(shù)組(淺拷貝):

const clone = arr => arr.slice(0)

更多詳細(xì)內(nèi)容可查閱淺拷貝和深拷貝

someevery

這兩個(gè)方法類似斷言(assert),返回一個(gè)布爾值,表示判斷數(shù)組成員是否符合某種條件。

在前面方法的介紹中,我們已經(jīng)大致了解了 everysome 方法的工作原理,下面是您可以從中獲得的一些附加功能:

  • Array.everyArray.some 可以接受第二個(gè)參數(shù),該參數(shù)將在回調(diào)函數(shù)的執(zhí)行中用作 this 參數(shù)。
  • 回調(diào)函數(shù)可以接受兩個(gè)額外的參數(shù):當(dāng)前項(xiàng)的索引和對(duì)調(diào)用該方法的數(shù)組的引用。

來看看一個(gè)示例:

const obj = { name: 'Daffodil' }
const arr = [1, 2, 3, 4, 5, 6]

arr.every(function (el, i, arr) {
  return el > i && arr[i] === el && this === obj
}, obj) // true
  • 每個(gè)元素都大于其索引
  • arr[i](其中 i 當(dāng)前索引與當(dāng)前元素相同)
  • 我們提供了 obj 作為 this 參數(shù)的引用,因此 this 等于 obj

注意:對(duì)于空數(shù)組,some 方法返回 falseevery 方法返回 true,回調(diào)函數(shù)都不會(huì)執(zhí)行。

const isEven = x => x % 2 === 0

[].some(isEven) // false
[].every(isEven) // true

someevery 方法還可以接受第二個(gè)參數(shù),用來綁定參數(shù)函數(shù)內(nèi)部的 this 變量。

通過索引獲取元素

const list = [1, 2, 3, 4, 5]
list[1]                 // 2
list.indexOf(2)         // 1

通過索引獲取數(shù)組的子集

不改變?cè)瓟?shù)組

list.slice(0,1)         // [1]
list.slice(1)           // [2, 3, 4, 5]
list.slice(1,2)         // [2]

改變?cè)瓟?shù)組

re = list.splice(1)     // re = [2, 3, 4, 5]  list == [1]
re = list.splice(1,2)   // re = [2, 3]      list == [1, 4, 5]

刪除元素

const list = [1, 2, 3, 4, 5]
list.pop()              // 5    list == [1, 2, 3, 4]
list.shift()            // 1    list == [2, 3, 4, 5]
list.splice(2, 1)       // [3]  list == [1, 2, 3, 4]

替換元素

const list = [1, 2, 3, 4, 5]

list.splice(2, 1, 6)    // list == [1, 2, 6, 4, 5]

插入

const list = [1, 2, 3, 4, 5]

// 指定元素之后插入
list.splice(list.indexOf(2) + 1, 0, 1) // [1, 2, 1, 3, 4, 5]

// 指定元素之前插入
list.splice(list.indexOf(2), 0, 6) // [1, 6, 2, 1, 3, 4, 5]

添加元素

不改變?cè)瓟?shù)組

list.concat([6])      // [1, 2, 3, 4, 5, 6]

改變?cè)瓟?shù)組

list.push(6)            // list == [1, 2, 3, 4, 5, 6]
list.unshift(6)         // list == [6, 5, 4, 3, 2, 1]
list.splice(2, 0, 6)    // list == [1, 2, 6, 3, 4, 5]

更多資料

以下整理了過往寫過關(guān)于數(shù)組的文章:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容