我正在学习underscore.js和javascript编程。 虽然我看到了下划线的来源,但我无法理解它的某些部分。
我无法理解为什么它在_.negate中使用'this'应用,因为其他部分接收'context'并使用它们。 以下是源代码。
https://github.com/jashkenas/underscore/blob/master/underscore.js
_.negate = function(predicate) {
return function() {
return !predicate.apply(this, arguments);
};
};
使用_.negate的地方是_.reject和_.omit。 看到_.reject的代码,它接收'context'并将其用于上下文。
_.filter = _.select = function(obj, predicate, context) {
var results = [];
if (obj == null) return results;
if (nativeFilter && obj.filter === nativeFilter) {
return obj.filter(predicate, context);
}
each(obj, function(value, index, list) {
if (predicate.call(context, value, index, list)) results.push(value);
});
return results;
};
_.reject = function(obj, predicate, context) {
return _.filter(obj, _.negate(predicate), context);
};
请给我一些解释。 提前谢谢。
答案 0 :(得分:3)
apply
来电一次做两件事:
this
内有效的predicate
。predicate
,而不必关心使用了多少参数。arguments
, (2)应该足够清楚; arguments
是一个类似于Array的对象,它保存函数的当前参数列表,JavaScript中的所有函数都是可变参数(尽管它们的定义是什么),arguments
是你如何使用参数知道有多少。
(1),快速查看_.negate
返回值的使用方式。在_.filter
内,使用call
调用predicate
:
predicate.call(context, value, index, list)
将this
设置为context
内的predicate
。如果predicate
实际上是_.negate(original_predicate)
,则实际上就是这样:
var f = function() {
return !original_predicate.apply(this, arguments);
};
f.call(context, ...)
所以original_predicate
将被调用,如original_predicate.apply(context, arguments)
,指定的this
(即context
)将在original_predicate
执行时生效。
如果_.negate
刚才这样做了:
return function(a, b, c) {
return !predicate(a, b, c);
};
然后会发生两件坏事:
context
将丢失。_.filter
就足够了,但可能不适用于_.negate
的其他用途。失去context
的跟踪会破坏大量代码,使用Function.prototype.apply
指定this
恰好可以免费解决参数列表问题。