前阵子在项目中有用到 reduce()
方法,当时不是很理解,后来空了学习了一下,有了一点小收获,记之~
用法
Array.prototype.reduce()
方法对数组中的每个元素执行指定回调函数,将其结果汇总为单个返回值。这个方法接收两个参数:
回调函数(必选),执行数组中每个值 (如果没有提供初始值则第一个值除外)的函数,包含四个参数:
accumulator(累计器),累计回调的返回值,值为上一次调用回调时返回的累积值或者初始值
currentValue,数组中正在处理的元素
index,数组中正在处理的当前元素的索引。如果提供了初始值,则起始索引号为0,否则从索引1起始
array,调用reduce()的数组,即源数组
初始值(可选),作为第一次调用回调函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用
reduce()
将报错
[1,2,3].reduce((accumulator, currentValue) => {
return accumulator + currentValue
})
// 1 + 2 + 3
// 6
[1,2,3].reduce((accumulator, currentValue) => {
return accumulator + currentValue
}, 1)
// 1 + 1 + 2 + 3
// 7
[].reduce((accumulator, currentValue) => {
return accumulator + currentValue
})
// 报错
// Uncaught TypeError: Reduce of empty array with no initial value
// at Array.reduce (<anonymous>)
// at <anonymous>:1:4
filter/find/forEach/map/reduce 的对比
这几个方法我总是会混淆,列了个表格方便对比
方法名 | 描述 | 语法 | 参数1 | 参数2 | 返回值 |
---|---|---|---|---|---|
filter | 返回满足所提供回调函数筛选条件的所有元素或空数组 | var newArray = arr.filter(callback(element[, index[, array]])[, thisArg]) | 用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数:element 当前遍历到的元素 index 可选 当前遍历到的索引array 可选 数组本身 |
执行回调时用作this 的对象 |
一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组 |
find | 返回满足所提供回调函数筛选条件的第一个元素的值或 undefined |
arr.find(callback(element[, index[, array]])[, thisArg]) | 在数组每一项上执行的函数,它接受以下三个参数: element 当前遍历到的元素 index 可选 当前遍历到的索引array 可选 数组本身 |
执行回调时用作this 的对象 |
数组中第一个满足所提供测试函数的元素的值,否则返回 undefined |
forEach | 对数组的每个元素执行一次提供的回调函数 | arr.forEach(callback(currentValue [, index [, array]])[, thisArg]) | 为数组中每个元素执行的函数,它接受以下三个参数: element 当前遍历到的元素 index 可选 当前遍历到的索引array 可选 数组本身 |
执行回调时用作this 的对象 |
undefined |
map | 返回数组中的每个元素调用一次提供的函数后组合形成的新数组 | var new_array = arr.map(function callback(currentValue[, index[, array]]) { // Return element for new_array }[, thisArg]) |
生成新数组元素的函数,它接受以下三个参数: element 当前遍历到的元素 index 可选 当前遍历到的索引array 可选 数组本身 |
执行回调时用作this 的对象 |
一个由原数组每个元素执行回调函数的结果组成的新数组 |
reduce | 返回数组中的每个元素升序调用一次提供的函数后汇总而成的值 | arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue]) | 执行数组中每个值 (如果没有提供 initialValue则第一个值除外 )的函数,它接受以下四个参数:accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue element 当前遍历到的元素 index 可选 当前遍历到的索引array 可选 数组本身 |
作为第一次调用 callback 函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素 |
函数累计处理的结果 |
使用 reduce 实现 filter
if (!Array.prototype.filterUsingReduce) {
Array.prototype.filterUsingReduce = function(callback, thisArg) {
return this.reduce(function(filterArray, currentValue, index, array) {
if (callback.call(thisArg, currentValue, index, array)) {
filterArray.push(currentValue)
}
return filterArray
}, [])
}
}
[1, 4, 9, 16].filterUsingReduce(
(currentValue) => currentValue > 10
) // [16]
使用 reduce 实现 find
if (!Array.prototype.findUsingReduce) {
Array.prototype.findUsingReduce = function(callback, thisArg) {
return this.reduce(function(findArray, currentValue, index, array) {
if (callback.call(thisArg, currentValue, index, array)) {
if (findArray instanceof Array && findArray.length === 0) {
findArray = currentValue
}
}
if ((index === array.length - 1) && findArray instanceof Array && findArray.length === 0) {
findArray = undefined
}
return findArray
}, [])
}
}
[1, 4, 9, 16].findUsingReduce(
(currentValue) => currentValue % 2 === 0
) // [4]
使用 reduce 实现 forEach
if (!Array.prototype.forEachUsingReduce) {
Array.prototype.forEachUsingReduce = function(callback, thisArg) {
this.reduce(function(forEachArray, currentValue, index, array) {
callback.call(thisArg, currentValue, index, array)
}, [])
}
}
const array1 = ['a', 'b', 'c'];
array1.forEachUsingReduce(element => console.log(`${element}: ${element+1}`));
// a: a1
// b: b1
// c: c1
使用 reduce 实现 map
if (!Array.prototype.mapUsingReduce) {
Array.prototype.mapUsingReduce = function(callback, thisArg) {
return this.reduce(function(mappedArray, currentValue, index, array) {
mappedArray[index] = callback.call(thisArg, currentValue, index, array)
return mappedArray
}, [])
}
}
[1, 4, 9, 16].mapUsingReduce(
(currentValue, index, array) => currentValue + index + array.length
) // [5, 9, 15, 23]
参考文章:
以前我没得选,现在我只想用 Array.prototype.reduce
生动形象解释forEach、filter、map、some、every、find、findIndex、reduce间的区别