理解“fnull”函数和“fnull”中的参数

时间:2014-03-12 14:12:53

标签: javascript functional-programming underscore.js

问题

我正在使用本书#34; Functional Javascript"来学习函数式编程。目前,我对fnull方法的控制台输出感到非常困惑。我正在寻找对正在发生的事情的解释,以及为什么我要观察我观察到的结果。

我怀疑额外的参数是迭代器和上下文。但是,fnull定义的函数只接受两个参数:total和n。迭代器和上下文来自哪里?

代码

JSFiddle

function existy(x) { return x != null };

function fnull(fun /*, defaults */) {
    var defaults = _.rest(arguments);

    return function(/* args */) {
        console.log("checking " + arguments[1]);
        var args = _.map(arguments, function(e, i) {
            console.log(e + "," + i);
            return existy(e) ? e : defaults[i];
        });

        return fun.apply(null, args);
    };
};

var safeMult = fnull(function(total, n) { return total * n }, 1, 1);

console.log(_.reduce([1,2,3,null,5], safeMult));

输出

checking 2
1,0
2,1
1,2            /* <-- Where do these arguments come from? */
1,2,3,,5,3     /* <-- */
checking 3
2,0
3,1
2,2
1,2,3,,5,3
checking null
6,0
null,1
3,2
1,2,3,,5,3
checking 5
6,0
5,1
4,2
1,2,3,,5,3
30 

[编辑如下]

减少来源

查看reduce方法的源代码,它会带来迭代器和上下文。因此,即使fun使​​用total和n,也会提供迭代器和上下文。

以下是来自underscore.js网站的reduce方法的来源:

_.reduce = _.foldl = _.inject = function(obj, iterator, memo, context) {
    var initial = arguments.length > 2;
    if (obj == null) obj = [];
    if (nativeReduce && obj.reduce === nativeReduce) {
      if (context) iterator = _.bind(iterator, context);
      return initial ? obj.reduce(iterator, memo) : obj.reduce(iterator);
    }
    each(obj, function(value, index, list) {
      if (!initial) {
        memo = value;
        initial = true;
      } else {
        memo = iterator.call(context, memo, value, index, list);
      }
    });
    if (!initial) throw new TypeError(reduceError);
    return memo;
  };

1 个答案:

答案 0 :(得分:0)

首先,fnull定义的函数接受任意数量的参数。它是由fnull返回的函数。

function fnull(...) {
    ...
    return function(/* args */) { // <-- this is the function defined by fnull
        ....
    }
} 

传递给fnullfunction(total, n) { return total * n })的函数存储在fun的{​​{1}}参数中。换句话说:

  • fnullsafeMult
  • 的返回函数
  • fnullfun

您在控制台上写的内容是function(total, n) { return total * n }传递给safeMult的参数。