我正在从下划线库重新创建函数,但在尝试实现_.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)
)?
答案 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
引用,因此它是真实的;所以!isEven
是false
。不是你想要的。 : - )
您的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));
};