在JS中调用函数时如何使用逻辑NOT(!)运算符?

时间:2015-09-22 15:42:04

标签: javascript operators underscore.js logical-operators

我正在从下划线库重新创建函数,但在尝试实现_.reject()函数时遇到了障碍。出于这个问题的目的,我将包含我为三个函数编写的代码:_.each()_.filter()_.reject()

_.each = function(collection, iterator) {
  if (Array.isArray(collection)) {
    for (var i = 0; i < collection.length; i++) {
      iterator(collection[i], i, collection);
    }
  } else {
    for (var i in collection) {
      iterator(collection[i], i, collection);
    }
  }
};

_.filter = function(collection, test) {
    var results = [];

    _.each(collection, function(i) {
      if (test(i)) {
        results.push(i);
      }
    })

    return results;
};

以下是我遇到问题的函数的代码,_.reject()方法以及我传入的isEven()函数作为test参数。

_.reject = function(collection, test) {
    return _.filter(collection, !test);
}; 

var isEven = function(x) {
    if (x % 2 === 0) return true;
    return false;
};

根据MDN's page on Expressions and Operators,逻辑NOT(!)运算符Returns false if its single operand can be converted to true; otherwise, returns true.

但是,当我运行以下代码_.reject([1,2,3], isEven)时,我收到错误消息test is not a function。为什么我在调用函数时无法使用!运算符(例如_.filter([1,2,3], !isEven))?

1 个答案:

答案 0 :(得分:6)

当你引用一个函数而不是调用它时,你指的是函数的对象引用:

function foo() {
    alert("Hi there");
}

var f = foo; // <== Getting the function's reference, not calling it
f();         // <== Now we call it

所以!isEven会否定函数引用。由于isEven是非null引用,因此它是真实的;所以!isEvenfalse。不是你想要的。 : - )

您的reject可以使用调用test的函数编写并反转其返回值:

_.reject = function(collection, test) {
  return _.filter(collection, function(e) { return !test(e); });
};

或者如果你想使用函数式编程方法,你可以编写一个函数,当被调用时,它将返回一个 new 函数,否定返回值:

function not(f) {
    return function() {
        return !f.apply(this, arguments);
    };
}

然后,您想要反转回调的含义,只需使用invert

_.reject = function(collection, test) {
  return _.filter(collection, not(test));
};