关于reduce()的问题

function getSum(total, num) {
    return total + Math.round(num);
}
function myFunction(numbers) {
    return numbers.reduce(getSum, 0);// 24
    return numbers.reduce(getSum);// 23.5 为什么改变了传递给函数的初始值,得出的结果不一样?
}

myFunction([15.5, 2.3, 1.1, 4.7]);
var numbers = [65, 44, 12, 4];

function getSum(total, num) {
    return total + num;
}
function myFunction(item) {
    document.getElementById("demo").innerHTML = numbers.reduce(getSum, 0);// 125
    document.getElementById("demo").innerHTML = numbers.reduce(getSum);// 125 为什么这里没有改变
}
阅读 1.8k
2 个回答

你若不指定默认值,那么total参数第一轮计算中就是第一个数。
[15.5, 2.3, 1.1, 4.7]这里相当于 15.5是第一个total(没参与四舍五入),然后不断加后面四舍五入的数,结果就是23.5; 如果设置了total默认值0,它把后面所有的数都四舍五入后相加了,故是24.

第二个问题不用解答了,你肯定也明白,因为里面都是整数,不会出现差异。

首先解释一下reduce函数的参数:

callback

执行数组中每个值的函数,包含四个参数:
  • accumulator
    累加器累加回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(如下所示)。
  • currentValue
    数组中正在处理的元素。
  • currentIndex可选
    数组中正在处理的当前元素的索引。 如果提供了initialValue,则索引号为0,否则为索引为1。
  • array可选
    调用reduce的数组

initialValue可选

用作第一个调用 callback的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错

返回值

函数累计处理的结果

文档还有一个polyfill的实现,看一下实现就明白了。

if (!Array.prototype.reduce) {
  Object.defineProperty(Array.prototype, 'reduce', {
    value: function(callback /*, initialValue*/) {
      if (this === null) {
        throw new TypeError( 'Array.prototype.reduce ' + 
          'called on null or undefined' );
      }
      if (typeof callback !== 'function') {
        throw new TypeError( callback +
          ' is not a function');
      }

      // 1. Let O be ? ToObject(this value).
      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0; 

      // Steps 3, 4, 5, 6, 7      
      var k = 0; 
      var value;

      if (arguments.length >= 2) {
        value = arguments[1];
      } else {
        while (k < len && !(k in o)) {
          k++; 
        }

        // 3. If len is 0 and initialValue is not present,
        //    throw a TypeError exception.
        if (k >= len) {
          throw new TypeError( 'Reduce of empty array ' +
            'with no initial value' );
        }
        value = o[k++];
      }

      // 8. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kPresent be ? HasProperty(O, Pk).
        // c. If kPresent is true, then
        //    i.  Let kValue be ? Get(O, Pk).
        //    ii. Let accumulator be ? Call(
        //          callbackfn, undefined,
        //          « accumulator, kValue, k, O »).
        if (k in o) {
          value = callback(value, o[k], k, o);
        }

        // d. Increase k by 1.      
        k++;
      }

      // 9. Return accumulator.
      return value;
    }
  });
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题