reduce

2017-11-10  本文已影响0人  伊各的诗与代码

原生的reduce方法只适用于数组,且方向固定为从左向右。

underscore中的reduce与reduceRight分别支持两个方向的迭代,且支持对对象的操作。

 _.reduce = _.foldl = _.inject = createReduce(1);
 _.reduceRight = _.foldr = createReduce(-1);

其底层实现均为createReduce方法。

createReduce

//dir决定迭代方向,-1为从右向左,1为从左向右
var createReduce = function(dir) {
    // Wrap code that reassigns argument variables in a separate function than
    // the one that accesses `arguments.length` to avoid a perf hit. (#1991)
    //这里是迭代的核心函数
    var reducer = function(obj, iteratee, memo, initial) {
      //处理数组与对象的不同
      var keys = !isArrayLike(obj) && _.keys(obj),
          length = (keys || obj).length,
          //迭代方向
          index = dir > 0 ? 0 : length - 1;
      //是否提供最初与数组或对象进行迭代的数据
      if (!initial) {
        memo = obj[keys ? keys[index] : index];
        //需要将起始位置向迭代方向移动一位
        index += dir;
      }
      //迭代
      for (; index >= 0 && index < length; index += dir) {
        var currentKey = keys ? keys[index] : index;
        memo = iteratee(memo, obj[currentKey], currentKey, obj);
      }
      return memo;
    };

    return function(obj, iteratee, memo, context) {
      //initial变量标识是否提供最初的迭代数据
      var initial = arguments.length >= 3;
      return reducer(obj, optimizeCb(iteratee, context, 4), memo, initial);
    };
  };
上一篇下一篇

猜你喜欢

热点阅读