15个必知的JavaScript数组方法

75 阅读8分钟

15种必知的JavaScript数组方法

数组是很奇妙的,也是JavaScript中非常特殊的类型。有许多有用的内置属性和方法,可以帮助你解决任何涉及数组的任务。今天,我们将讨论每个开发者都应该知道的15个数组方法。

  • some()
  • every()
  • reduce()
  • map()
  • flat()
  • filter()
  • forEach()
  • findIndex()
  • find()
  • sort()
  • concat()
  • fill()
  • 包括()
  • 反转()
  • flatMap()

注意这个列表没有列举,因为我不认为一个方法比另一个方法更重要,它们中的每一个都会解决不同的问题,因此我们必须熟悉所有的方法。


some()

some() 测试数组中是否至少有一个元素通过了由callback 函数实现的测试。callback 函数将收到3个参数,项目、索引和整个数组。此外,在执行callback 时,可以通过参数thisArg ,为this 赋值。

定义。

arr.some(callback(element[, index[, array]])[, thisArg])

例子。

const a = [1, 2, 3, 5, 8].some(item => item > 5)
const b = [1, 2, 3, 4, 5].some(item => item > 5)

console.log(a)
console.log(b)


---------
Output
---------
> true
> false

every()

every() 方法与some() 方法类似,但是它测试数组中的所有元素是否通过了callback 函数实现的测试。

定义:举例说明。

arr.every(callback(element[, index[, array]])[, thisArg])

例子。

const a = [10, 9, 8, 7, 6].every(item => item > 5)
const b = [7, 6, 5].every(item => item > 5)

console.log(a)
console.log(b)


---------
Output
---------
> true
> false

reduce()

reduce() 方法为数组中存在的每个分配值执行一次callback 函数,需要 4 个参数。

  1. 累加器
  2. 当前值
  3. currentIndex
  4. 数组

第一次调用callbackaccumulatorcurrentValue ,如果提供了initialValue ,则可以是数组中的第一个值。

定义。

arr.reduce(callback( accumulator, currentValue[, index[, array]] )[, initialValue])

reduce()如何工作

让我们通过一个例子来看看reduce() 是如何工作的。

[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => accumulator + currentValue)

如果我们按部就班,把所有的参数加上callback 的结果值放在一个表格里,我们会得到以下结果。

#累加器当前值currentIndex数组返回值
1010[0, 1, 2, 3, 4]1
2121[0, 1, 2, 3, 4]3
3332[0, 1, 2, 3, 4]6
4643[0, 1, 2, 3, 4]10

而最终的结果将是10 。在我们的特殊情况下,我没有提供一个初始值,让我们接下来尝试一下

const initialValue = 10
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => accumulator + currentValue, initialValue)

有了这个新方案,我们的表格就会变成这样。

#累积器当前值currentIndex数组返回值
11000[0, 1, 2, 3, 4]10
21011[0, 1, 2, 3, 4]11
31122[0, 1, 2, 3, 4]13
41333[0, 1, 2, 3, 4]16
51644[0, 1, 2, 3, 4]20

最后得出的值是20

reduce() 这个函数非常棒,它有几个用途,如对一个数组或对象数组中的所有值进行求和,对数组中的特定项目进行计数,对对象进行分组,合并数组中的对象,删除重复的内容等。


map()

map() 方法创建了一个新的数组,该数组中的每个元素都被填充了callback 函数的结果。与其他方法类似,callback 函数将收到3个参数:currentValue,index, 和array 。和reduce()的情况一样,callback ,只对数组中已经赋值的索引进行调用(包括undefined )。

定义。

arr.map(callback( currentValue[, index[, array]])[, thisArg])

在使用map() 时一定要小心,记住每次调用都会创建一个新的数组,如果你实际上不需要这个数组,而只是想迭代,可以用forEach()for-of 来代替。

例子。

const numbers = [1, 2, 3, 4, 5]
const doubled = numbers.map(value => value * 2)

console.log(doubled)

---------
Output
---------
> (5) [2, 4, 6, 8, 10]

正如我们所提到的map() ,将创建一个新的数组,所以下面的内容就是一个结果。

const numbers = [1, 2, 3, 4, 5]
const numbers2 = numbers.map(value => value)
console.log('numbers', numbers)
console.log('numbers2', numbers2)
console.log(numbers === numbers2)

---------
Output
---------
numbers (5) [1, 2, 3, 4, 5]
numbers2 (5) [1, 2, 3, 4, 5]
false

即使每个数组包含完全相同的元素,它们也不是相同的引用,因此numbers === numbers2 ,解析为false。


flat()

flat() 方法创建一个新的数组,所有的子数组元素都被递归到它里面,直到指定的深度。默认情况下,它将平坦化1级。

定义。

arr.flat([depth])

例子。

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

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

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

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

---------
Output
---------
> (4) [1, 2, 3, 4]
> (5) [1, 2, 3, 4, Array(2)]
> (6) [1, 2, 3, 4, 5, 6]
> (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

注意,如果我们想递归地平铺所有层次,我们可以把Infinity 作为函数的参数。


filter()

map() 一起,我认为这是我的最爱之一。filter() 方法创建一个新的数组,其中包含所有通过callback 函数实现的测试的元素。

定义。

arr.filter(callback(element[, index, [array]])[, thisArg])

例子。

const array = [-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

function isPrime(num) {
  for (let i = 2; num > i; i++) {
    if (num % i == 0) {
      return false
    }
  }
  return num > 1
}

console.log(array.filter(isPrime))

---------
Output
---------
> (6) [2, 3, 5, 7, 11, 13]

forEach()

forEach() 方法对每个数组元素执行一次提供的函数。

定义。

arr.forEach(callback(currentValue [, index [, array]])[, thisArg])

例子。

const array = [1, 2, 3, 4, 5]
array.forEach((item) => console.log(item))

---------
Output
---------
1
2
3
4
5

在使用时有两个重要的注意事项forEach()

  • 除了抛出一个异常外,没有办法停止或中断一个forEach() 循环。
  • forEach() 预计一个同步的 ,它不会等待承诺被解决。callback

让我们看一个后者的例子。

let ratings = [5, 4, 5]
let sum = 0

let sumFunction = async function (a, b)
{
  return a + b
}

ratings.forEach(async function(rating) {
  sum = await sumFunction(sum, rating)
})

console.log(sum)

---------
Output
---------
0

尽管我们期望变量sum 已经积累了数组中的所有值,并且其值为14 ,但由于forEach() 语句结束时没有等待承诺,因此在变量sum 被更新之前执行了console.log 语句,所以输出结果为0 。所以要非常注意这种情况,因为它可能导致你的代码产生意外的结果。


findIndex()

findIndex() 方法返回数组中满足所提供的callback 函数的第一个元素的索引。否则,它返回-1,表示没有元素通过测试。与其他方法不同的是,findIndex() ,即使是未赋值的索引,也会执行callback 函数。

定义。

arr.findIndex(callback( element[, index[, array]] )[, thisArg])

例子。

function isPrime(num) {
  for (let i = 2; num > i; i++) {
    if (num % i == 0) {
      return false
    }
  }
  return num > 1
}

console.log([4, 6, 8, 9, 12].findIndex(isPrime))
console.log([4, 6, 7, 9, 12].findIndex(isPrime))

---------
Output
---------
-1
2

find()

find() 方法与findIndex() 方法类似,但是,它返回满足所提供的callback 函数的第一个元素的,应该是其索引。如果没有元素满足callback ,那么将返回undefined

定义。

arr.find(callback(element[, index[, array]])[, thisArg])

例子。

const inventory = [
  {name: 'apples', quantity: 2},
  {name: 'bananas', quantity: 0},
  {name: 'cherries', quantity: 5}
]

const result = inventory.find( ({ name }) => name === 'cherries' )

console.log(result)


---------
Output
---------
> {name: "cherries", quantity: 5}

sort()

sort() 函数是非常常见的,它只是允许我们对一个数组的元素进行原地排序,并返回排序数组。默认的排序顺序是升序。这个方法的复杂性和性能不能保证,因为它取决于实现。

定义。

arr.sort([compareFunction])

例子。

const numbers = [4, 2, 5, 1, 3]
numbers.sort((a, b) => a - b)
console.log(numbers)

---------
Output
---------
> (5) [1, 2, 3, 4, 5]

永远记住,排序是在原地进行的,所以。

const numbers = [4, 2, 5, 1, 3]
const numbers2 = numbers.sort((a, b) => a - b)

console.log('numbers', numbers)
console.log('numbers2', numbers2)
console.log(numbers === numbers2)

---------
Output
---------
numbers > (5) [1, 2, 3, 4, 5]
numbers2 > (5) [1, 2, 3, 4, 5]
true

排序函数将修改现有的数组,并返回对同一数组的引用,因此原始数组和返回的数组将是一样的。


concat()

concat() 方法用于将两个或多个数组合并成一个新的数组

定义。

const new_array = old_array.concat([value1[, value2[, ...[, valueN]]]])

例子。

const letters = ['a', 'b', 'c']
const numbers = [1, 2, 3]

console.log(letters.concat(numbers))

---------
Output
---------
> (6) ["a", "b", "c", 1, 2, 3]

fill()

fill() 方法将一个数组中的所有元素改变为一个静态值,从开始索引(默认为0 )到结束索引(默认为array.length )。更新将在原地发生,并将返回对同一数组的引用。

定义。

arr.fill(value[, start[, end]])

例子。

const original = [1, 2, 3]
const result = original.fill(4)
console.log('original', original)
console.log('result', result)
console.log(original === result)

---------
Output
---------
original > (3) [4, 4, 4]
result > (3) [4, 4, 4]
true

includes()

includes() 方法确定一个数组的条目中是否包含某个值,返回truefalse 。注意,includes() 方法在比较字符串和字符时是区分大小写的。

定义。

arr.includes(valueToFind[, fromIndex])

举例说明。

console.log([1, 2, 3].includes(2))
console.log([1, 2, 3].includes(4))

---------
Output
---------
true
false

reverse()

reverse() 方法将一个数组原地反转。我们所说的反转是指该函数将对数组的元素进行转置,第一个元素将变成最后一个,而最后一个变成第一个元素。这个操作将使原数组发生变化,并返回一个相同的引用。

定义。

a.reverse()

例子。

console.log([1, 2, 3].reverse())

---------
Output
---------
> (3) [3, 2, 1]

flatMap()

flatMap() 方法对数组中的每个元素应用一个函数,然后将结果平铺成一个数组。它在一个函数中结合了flat()map()

定义。

arr.flatMap(callback(currentValue[, index[, array]])[, thisArg])

例子。

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

const a = array.flatMap(arr => arr * 10)


// With .flat() and .map()
const b = array.flat().map(arr => arr * 10)

console.log('flatMap', a)
console.log('flat&map', b)

---------
Output
---------
flatMap (5) [10, 20, 30, 40, 50]
flat&map (5) [10, 20, 30, 40, 50]

总结

JavaScript数组有一些伟大的方法,可以简化我们的开发工作。了解它们可以为我们节省一些时间,在某些情况下甚至可以提高我们代码的性能。我希望你今天学到了一些新的数组方法,或者刷新了一些旧的概念,你可以在你的下一个项目中使用。