**reduce()** 方法对数组中的每个元素执行一个由您提供的reducer函数(升序执行),将其结果汇总为单个返回值。
语法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
参数
-
callback执行数组中每个值 (如果没有提供
initialValue则第一个值除外)的函数,包含四个参数:**
accumulator**累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。currentValue数组中正在处理的元素。index可选数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。array可选调用reduce()的数组 -
initialValue可选作为第一次调用
callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。
返回值
函数累计处理的结果
描述
reduce为数组中的每一个元素依次执行callback函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:
accumulator 累计器currentValue 当前值currentIndex 当前索引array 数组
回调函数第一次执行时,accumulator 和currentValue的取值有两种情况:如果调用reduce()时提供了initialValue,accumulator取值为initialValue,currentValue取数组中的第一个值;如果没有提供 initialValue,那么accumulator取数组中的第一个值,currentValue取数组中的第二个值。
**注意:**如果没有提供initialValue,reduce 会从索引1的地方开始执行 callback 方法,跳过第一个索引。如果提供initialValue,从索引0开始。
如果数组为空且没有提供initialValue,会抛出TypeError 。如果数组仅有一个元素(无论位置如何)并且没有提供initialValue, 或者有提供initialValue但是数组为空,那么此唯一值将被返回并且callback不会被执行。
提供初始值通常更安全,正如下面的例子,如果没有提供initialValue,则可能有四种输出:
var maxCallback = ( acc, cur ) => Math.max( acc.x, cur.x );
var maxCallback2 = ( max, cur ) => Math.max( max, cur );
// reduce() 没有初始值
[ { x: 2 }, { x: 22 }, { x: 42 } ].reduce( maxCallback ); // NaN
[ { x: 2 }, { x: 22 } ].reduce( maxCallback ); // 22
[ { x: 2 } ].reduce( maxCallback ); // { x: 2 }
[ ].reduce( maxCallback ); // TypeError
// map/reduce; 这是更好的方案,即使传入空数组或更大数组也可正常执行
[ { x: 22 }, { x: 42 } ].map( el => el.x )
.reduce( maxCallback2, -Infinity );
reduce() 如何运行
假如运行下段reduce()代码:
[0, 1, 2, 3, 4].reduce(function(accumulator, currentValue, currentIndex, array){
return accumulator + currentValue;
});
callback 被调用四次,每次调用的参数和返回值如下表:
callback |
accumulator |
currentValue |
currentIndex |
array |
return value |
|---|---|---|---|---|---|
| first call | 0 |
1 |
1 |
[0, 1, 2, 3, 4] |
1 |
| second call | 1 |
2 |
2 |
[0, 1, 2, 3, 4] |
3 |
| third call | 3 |
3 |
3 |
[0, 1, 2, 3, 4] |
6 |
| fourth call | 6 |
4 |
4 |
[0, 1, 2, 3, 4] |
10 |
由reduce返回的值将是最后一次回调返回值(10)。
你还可以使用箭头函数来代替完整的函数。 下面的代码将产生与上面的代码相同的输出:
[0, 1, 2, 3, 4].reduce((prev, curr) => prev + curr );
如果你打算提供一个初始值作为reduce()方法的第二个参数,以下是运行过程及结果:
[0, 1, 2, 3, 4].reduce((accumulator, currentValue, currentIndex, array) => { return accumulator + currentValue; },
callback |
accumulator |
currentValue |
currentIndex |
array |
return value |
|---|---|---|---|---|---|
| first call | 10 |
0 |
0 |
[0, 1, 2, 3, 4] |
10 |
| second call | 10 |
1 |
1 |
[0, 1, 2, 3, 4] |
11 |
| third call | 11 |
2 |
2 |
[0, 1, 2, 3, 4] |
13 |
| fourth call | 13 |
3 |
3 |
[0, 1, 2, 3, 4] |
16 |
| fifth call | 16 |
4 |
4 |
[0, 1, 2, 3, 4] |
20 |
这种情况下reduce()返回的值是20。