recude 函数为 js 数组中较难理解的一个函数,其定义如下:
定义
其中callback函数有四个参数:arr.reduce(callback,[initialValue])
previousValue
(第一次调用callback
函数时候,previousValue
值为reduce
函数的第二个参数initialValue
,如果没有initialValue
则previousValue
值为数组的第一个元素,currentValue
为第二个元素。第二次及以后的callback
函数调用previousValue
为上一次调用callback
函数的返回结果)currentValue
(数组中当前被处理的元素)index
(当前元素在数组中的索引,一般不用)array
(调用 reduce 的数组,一般不用)
用一句话来简单的概括就是:
- reduce函数,为数组中的每一个元素执行callback方法,并将每次callback方法的返回结果,作为下一次调用callback方法的参数 (通常也把这种思想叫做管道机制
pipeline
)
reduce函数常见的使用场景有:
数组的累加
var arry = [1, 2, 3, 4, 5, 6, 7]; var total = arry.reduce(function(sum, item) { return sum + item; }, 0); console.log(total);
计算字符串中各字符的出现次数
var str = 'abcdcbcddacabcdad'; var result = str.split('').reduce(function(res, cur) { res[cur] ? res[cur] ++ : res[cur] = 1 return res; }, {}) console.log(result);
管道函数调用
//假如有一个流程包含5个步骤,每一步的参数为上一步的执行结果 var init = 0; function step5(arg){return arg + 5;}; function step4(arg){return arg + 4;}; function step3(arg){return arg + 3;}; function step2(arg){return arg + 2;}; function step1(arg){return arg + 1;}; var result1 = step5( step4( step3( step2( step1( init ) ) ) ) ); console.log(result1) //等价于以下的写法 var result2 = [step1,step2,step3,step4,step5].reduce((a, b) => b(a), init); console.log(result2)
reduce
为ES5
中的一个新特性,所有使用reduce
实现的功能其实都能用for循环
来实现,一个简单的实现如下:
Array.prototype.reduce = function(callback, init) {
var result;
for(var i = 0 ;i < this.length; i++){
result = i == 0 ? callback(init, this[i]) : callback(result, this[i]);
}
return result;
}
更为严谨的实现可以查看es5-shim.js中对reduce
的实现