SOURCE

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 命令行工具 X clear

                    
>
console