Array.prototype.myReduce = function(callback, ...args) {
// 1. 校验 this
if (this == null) {
throw new TypeError('Array.prototype.myReduce called on null or undefined');
}
// 2. 校验回调
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
const O = Object(this);
const len = O.length >>> 0;
let k = 0;
let accumulator;
// 3. 核心修正:利用 rest 参数的 length 判断是否有初始值
// 这样就能完美区分 [].myReduce(cb) 和 [].myReduce(cb, undefined)
const hasInitial = args.length > 0;
const initialValue = args[0]; // 即使显式传入 undefined,args[0] 也是 undefined,但 length 为 1
if (hasInitial) {
accumulator = initialValue;
} else {
// 无初始值:查找第一个存在的元素
let found = false;
while (k < len) {
if (k in O) {
accumulator = O[k];
found = true;
k++;
break;
}
k++;
}
if (!found) {
throw new TypeError('Reduce of empty array with no initial value');
}
}
// 4. 遍历剩余索引
for (; k < len; k++) {
if (k in O) {
accumulator = callback(accumulator, O[k], k, O);
}
}
return accumulator;
};
console