我正在使用本书#34; Functional Javascript"来学习函数式编程。目前,我对fnull方法的控制台输出感到非常困惑。我正在寻找对正在发生的事情的解释,以及为什么我要观察我观察到的结果。
我怀疑额外的参数是迭代器和上下文。但是,fnull定义的函数只接受两个参数:total和n。迭代器和上下文来自哪里?
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;
};
答案 0 :(得分:0)
首先,fnull
定义的函数接受任意数量的参数。它是由fnull
返回的函数。
function fnull(...) {
...
return function(/* args */) { // <-- this is the function defined by fnull
....
}
}
传递给fnull
(function(total, n) { return total * n }
)的函数存储在fun
的{{1}}参数中。换句话说:
fnull
是safeMult
fnull
是fun
您在控制台上写的内容是function(total, n) { return total * n }
传递给safeMult
的参数。