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 个参数。
- 累加器
- 当前值
- currentIndex
- 数组
第一次调用callback ,accumulator 和currentValue ,如果提供了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 | 数组 | 返回值 |
|---|---|---|---|---|---|
| 1 | 0 | 1 | 0 | [0, 1, 2, 3, 4] | 1 |
| 2 | 1 | 2 | 1 | [0, 1, 2, 3, 4] | 3 |
| 3 | 3 | 3 | 2 | [0, 1, 2, 3, 4] | 6 |
| 4 | 6 | 4 | 3 | [0, 1, 2, 3, 4] | 10 |
而最终的结果将是10 。在我们的特殊情况下,我没有提供一个初始值,让我们接下来尝试一下
const initialValue = 10
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => accumulator + currentValue, initialValue)
有了这个新方案,我们的表格就会变成这样。
| # | 累积器 | 当前值 | currentIndex | 数组 | 返回值 |
|---|---|---|---|---|---|
| 1 | 10 | 0 | 0 | [0, 1, 2, 3, 4] | 10 |
| 2 | 10 | 1 | 1 | [0, 1, 2, 3, 4] | 11 |
| 3 | 11 | 2 | 2 | [0, 1, 2, 3, 4] | 13 |
| 4 | 13 | 3 | 3 | [0, 1, 2, 3, 4] | 16 |
| 5 | 16 | 4 | 4 | [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() 方法确定一个数组的条目中是否包含某个值,返回true 或false 。注意,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数组有一些伟大的方法,可以简化我们的开发工作。了解它们可以为我们节省一些时间,在某些情况下甚至可以提高我们代码的性能。我希望你今天学到了一些新的数组方法,或者刷新了一些旧的概念,你可以在你的下一个项目中使用。