reduce() 方法接收一個函數作為累加器(accumulator),數組中的每個值(從左到右)開始合並,最終為一個值。
參數
-
callback -
執行數組中每個值的函數,包含四個參數 -
-
previousValue - 上一次調用回調返回的值,或者是提供的初始值(initialValue)
-
currentValue - 數組中當前被處理的元素
-
index - 當前元素在數組中的索引
-
array -
調用
reduce的數組
-
-
initialValue - 作為第一次調用 callback 的第一個參數。
描述
reduce 為數組中的每一個元素依次執行回調函數,不包括數組中被刪除或從未被賦值的元素,接受四個參數:初始值(或者上一次回調函數的返回值),當前元素值,當前索引,調用 reduce 的數組。
回調函數第一次執行時,previousValue 和 currentValue 可以是一個值,如果 initialValue 在調用 reduce 時被提供,那么第一個 previousValue 等於 initialValue ,並且currentValue 等於數組中的第一個值;如果initialValue 未被提供,那么previousValue 等於數組中的第一個值,currentValue等於數組中的第二個值。
如果數組為空並且沒有提供initialValue, 會拋出TypeError 。如果數組僅有一個元素(無論位置如何)並且沒有提供initialValue, 或者有提供initialValue但是數組為空,那么此唯一值將被返回並且callback不會被執行。
例如執行下面的代碼
[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 | |
|---|---|---|---|---|---|
| 第一次調用 | 10 |
0 |
0 |
[0,1,2,3,4] |
10 |
| 第二次調用 | 10 |
1 |
1 |
[0,1,2,3,4] |
11 |
| 第三次調用 | 11 |
2 |
2 |
[0,1,2,3,4] |
13 |
| 第四次調用 | 13 |
3 |
3 |
[0,1,2,3,4] |
16 |
| 第五次調用 | 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 被添加到 ECMA-262 標准第 5 版;因此可能在某些實現環境中不被支持。可以將下面的代碼插入到腳本開頭來允許在那些未能原生支持 reduce 的實現環境中使用它。
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; }; }
參考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
