先放出reduce方法的MDN定义 developer.mozilla.org/zh-CN/docs/…
我们需要注意的点有以下几点: 1: reduce接收2个参数,一个是fn(数组每一项都要执行的函数), 一个是initValue(初始值); 2: reduce函数接收到的fn函数,fn又可以接受4个参数,分别是 acc(上次执行的累计结果),curItem(当前遍历到的数组项),index(当前遍历到的数组项的 index值), arr(源数组);
3: reduce接收到的参数如果只有fn的话,那么acc 累加结果默认是从源数组第1(index=0)项即arr[0]开始,并且遍历初始index是1,如果reduce接收到的参数,有fn,有initValue两项,那么 acc的累加结果默认初始值为initValue, 遍历初始index是 0;
4: 那么,从分析中得出,我们要判断reduce函数的参数个数,所以要用到arguments,这个就不能使用箭头函数来写,因为箭头函数没有arguments,没有caller.(不能通过initValue是否是undefined来判断reduce是否传入初始值,因为js reduce初始值为undefined的话,函数也会执行,只不过结果是NAN)
下面开始写代码: 因为是数组方法,所以肯定要挂到Array的 prototype上面:
let fn = (pre, cur)=>{return pre + cur};
let arr = [1,2,3,4,5]
Array.prototype.myReduce = function(fn, initValue){
//为什么不用箭头函数定义,上面说了原因了
if(Object.prototype.toString.call(fn) !== '[object Function]'){
throw new Error(' param is not correct')
}
let initIndex = arguments.length === 1 ? 1: 0;
let acc = arguments.length === 1? arr[0] : initValue;
for(let i =initIndex; i< arr.length; i++){
acc = fn(acc, arr[i], i, arr);
}
return acc
}
let result = arr.myReduce(fn)
console.log(result)