Summary
方法 reduce() 接收一个函数作为叠加器,让每个值(从左到右)缩减为一个值
Syntax
arr.reduce(callback,[initialValue])
Parameters
-
callback -
执行数组中每个值的函数,包含四个参数 -
-
previousValue - 上一次循环返回的值,或者初始值(initialValue),如果初始值被提供
-
currentValue -
当前操作值 -
index - 当前元素在数组中的索引
-
array -
调用的数组
-
-
initialValue -
第一次调用此函数的值
描述
reduce 为数组中的每一个元素依次执行回调函数,包括空元素,接受四个参数:初始值(或者上一次回调函数的返回值),当前值,当前索引,执行数组。
回调函数第一次执行时,previousValue 和 currentValue可以是一个值,如果initialValue 在调用 reduce 是被提供,那么第一个previousValue 等于 initialValue ,并且currentValue等于数组中的第一个值;如果initialValue 未被提供,那么previousValue 等于数组中的第一个值,currentValue等于数组中的第二个值。
假设以下reduce 执行
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
});
回调被执行四次,每次的参数和返回值如下表:
previousValue |
currentValue |
index |
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)
如果把初始值作为第二个参数传入reduce,最终返回值变为20,结果如下:
[0,1,2,3,4].reduce(function(previousValue, currentValue, index, array){
return previousValue + currentValue;
}, 10);
previousValue |
currentValue |
index |
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 |
例子
例子:将数组所有项相加
var total = [0, 1, 2, 3].reduce(function(a, b) {
return a + b;
});
// total == 6
例子: 数组扁平化
var flattened = [[0, 1], [2, 3], [4, 5]].reduce(function(a, b) {
return a.concat(b);
});
// flattened is [0, 1, 2, 3, 4, 5]
Polyfill
Array.prototype.reduce was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of reduce in implementations which do not natively support it.
if ('function' !== typeof Array.prototype.reduce) {
Array.prototype.reduce = function(callback, opt_initialValue){
'use strict';
if (null === this || 'undefined' === typeof this) {
// At the moment all modern browsers, that support strict mode, have
// native implementation of Array.prototype.reduce. For instance, IE8
// does not support strict mode, so this check is actually useless.
throw new TypeError(
'Array.prototype.reduce called on null or undefined');
}
if ('function' !== typeof callback) {
throw new TypeError(callback + ' is not a function');
}
var index, value,
length = this.length >>> 0,
isValueSet = false;
if (1 < arguments.length) {
value = opt_initialValue;
isValueSet = true;
}
for (index = 0; length > index; ++index) {
if (this.hasOwnProperty(index)) {
if (isValueSet) {
value = callback(value, this[index], index, this);
}
else {
value = this[index];
isValueSet = true;
}
}
}
if (!isValueSet) {
throw new TypeError('Reduce of empty array with no initial value');
}
return value;
};
}
Specifications
| Specification | Status | Comment |
|---|---|---|
| ECMAScript Language Specification 5.1th Edition (ECMA-262) | Standard | Initial definition. Implemented in JavaScript 1.8 |
| ECMAScript Language Specification 6th Edition (ECMA-262) | Draft |
Browser compatibility
| Feature | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
|---|---|---|---|---|---|
| Basic support | (Yes) | 3.0 (1.9) | 9 | 10.5 | 4.0 |
| Feature | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
|---|---|---|---|---|---|---|
| Basic support | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) | (Yes) |