我的回答

  1. [].reduce((a, b) => { a + b}, 0)
  1. Array.prototype.reduce = function(fn, prev) {
  2. if (!prev) prev = this[0]
  3. for (let i = 1; i < this.length; i++) {
  4. prev = fn.call(prev, this[i], i, this)
  5. }
  6. return prev
  7. }

参考回答

Array.reduce

简单介绍

  • 语法:arr.reduce(callback,[,initialValue])
  • 参数:
  • callback:针对每一项执行的函数

    account:初始值/上一次回调返回的值 current:当前值 index:可选,当前索引 scrouce:可选,原数组

  • initialValue:可选,累加的初始值

  • 描述:方法接收一个函数作为累加器,reduce 为数组中的每一个元素依次执行回调函数,不包括数中被删除或从未被赋值的元素

如果没有初始值,pre将使用数组中的第一个元素 在没有初始值的空数组上调用reduce将报错 在没有初始值的仅有一个元素的数组上使用reduce,那么callback不会被执行,此唯一值将被返回

解答小疑惑 - callback 执行次数

  1. [1, 2, 3, 4].reduce((pre, cur, index, array) => {
  2. console.log(pre, cur, index);
  3. return pre + cur;
  4. });
  5. // 此时代码没有初始值,callback执行3次 ----> pre=1,cur=2,index=1(第一次执行的时候)
  1. [1, 2, 3, 4].reduce((pre, cur, index, array) => {
  2. console.log(pre, cur, index);
  3. return pre + cur;
  4. }, 0);
  5. // 此时代码有初始值,callback执行4次 ----> pre=0,cur=1,index=0(第一次执行的时候)

实现

分析
  • Array.reduce是Array.prototype上的原型方法
  • Array.reduce 接收两个参数:callback函数和initialVaule初始值[可选]
  • 没有初始值 && 空数组 会进行报错
  • 没有初始值 && 数组长度为1 直接返回数组里的这一项,不需要执行callback
  • 没有初始值 && 数组长度大于1 正常流程走 index=1
  • 有初始值 && 数组长度大于1 正常流程走 index=0
  • reduce返回值是pre
  1. if (!Array.prototype.reduce) {
  2. Object.defineProperty(Array.prototype, "reduce", {
  3. value: function (callback) {
  4. if (this === null) {
  5. throw new TypeError("Array.prototype.reduce called on null or undefiend");
  6. }
  7. if (typeof callback !== "function") {
  8. throw new TypeError(callback + "is not a function");
  9. }
  10. var o = Object(this);
  11. // 位运算符
  12. // >>>是无符号右移运算符,保证结果为非负整数,是length值所要的数字。
  13. // (如果运算为NaN,length结果为0,在后续代码中遍历对象也不会抛出异常)
  14. var len = o.length >>> 0;
  15. var k = 0;
  16. var value;
  17. if (arguments.length >= 2) {
  18. value = arguments[1];
  19. } else {
  20. while (k < len && !(k in o)) {
  21. k++;
  22. }
  23. if (k >= len) {
  24. throw new TypeError("Reduce of empty array with no initial value");
  25. }
  26. value = o[k++];
  27. }
  28. while (k < len) {
  29. if (k in o) {
  30. value = callback(value, o[k], k, o);
  31. }
  32. k++;
  33. }
  34. return value;
  35. },
  36. });
  37. }
  1. const _reduce = function (fn, prev) {
  2. let i = arguments.length === 1 ? (prev = this[0], 1) : 0
  3. for (; i < this.length; i++) {
  4. prev = fn(prev, this[i], i, this)
  5. }
  6. return prev
  7. }
  8. Array.prototype._reduce = _reduce
  9. const sum = [1, 2, 3]._reduce((prev, cur) => {
  10. console.log(prev, cur)
  11. return prev + cur
  12. }, 3)