需要注意的点
- reduce 的 callback 接收三个参数,分别是上一轮结果的值,初始值和当前循环的下标
- reduce 第一个参数不是函数,报类型错误 "xxx is not a function"
- reduce 的目标数组为空数组,若传递了初始值,则直接返回初始值,不然报类型错误 "Reduce of empty array with no initial value"
- reduce 的目标数组只有一个元素,返回该元素,不进行迭代。
Array.prototype._reduce = function reduce(cb, initial) {
// this 即为需要迭代的数组
// 如果传递了第二个参数 则从数组第一个元素开始循环
let self = this,
i = 0,
result = initial,
len = self.length,
isInit = typeof initial === 'undefined' ? false : true;
if (typeof cb !== 'function') throw new TypeError(`${ cb } is not a function!`)
// 数组为空且没有初始值 报错
if (len === 0 && !isInit) throw newTypeError('Reduce of empty array with no initial value');
// 数组为空 有初始值 返回初始值
if (len === 0 && isInit) return initial;
// 数组有一项 且没有初始值
if (len === 1 && !isInit) return self[0];
// 没传递初始值 从数组第二个开始循环 第一个元素作为初始的 result
if (!isInit) {
result = self[0];
i = 1;
}
for (; i < self.length; i++) {
result = cb(result, self[i], i);
}
return result;
}
let arr = [1, 2, 3, 4];
let total = arr._reduce(function(prev, next) {
return prev + next
}, 0);
console.log(total);
来一版纯净代码:
Array.prototype._reduce = function reduce(cb, initial) {
let self = this,
i = 0,
result = initial,
len = self.length,
isInit = typeof initial === 'undefined' ? false : true;
if (typeof cb !== 'function') {
throw new TypeError(`${ cb } is not a function!`);
}
if (len === 0 && !isInit) {
throw newTypeError('Reduce of empty array with no initial value');
}
if (len === 0 && isInit) return initial;
if (len === 1 && !isInit) return self[0];
if (!isInit) {
result = self[0];
i = 1;
}
for (; i < self.length; i++) {
result = cb(result, self[i], i);
}
return result;
}
let arr = [1, 2, 3, 4];
let total = arr._reduce(function(prev, next) {
return prev + next
}, 0);
console.log(total);