为什么' _。否定'使用适用于'这个' underscore.js中的参数?

时间:2014-03-14 05:05:50

标签: javascript underscore.js

我正在学习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);
};

请给我一些解释。 提前谢谢。

1 个答案:

答案 0 :(得分:3)

apply来电一次做两件事:

  1. 设置this内有效的predicate
  2. 它将匿名函数的参数列表直接传递给predicate,而不必关心使用了多少参数。
  3. 如果您了解JavaScript中的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);
    };
    
    然后会发生两件坏事:

    1. 指定的context将丢失。
    2. 只有三个论点可以通过。这对于_.filter就足够了,但可能不适用于_.negate的其他用途。
    3. 失去context的跟踪会破坏大量代码,使用Function.prototype.apply指定this恰好可以免费解决参数列表问题。