2015-09-22 1 views
1

Я воссоздаю функции из библиотеки подчеркивания, но я запускаю блокпост при попытке реализовать функцию _.reject(). Для целей этого вопроса я включу код, который я написал для трех функций: _.each(), _.filter() и _.reject().Как использовать логический оператор NOT (!) При вызове функций в JS?

_.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, логического НЕ (!) Оператор 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

Похоже, что, возможно, вы хотите '! Test()' вместо этого. Отрицание функции бессмысленно. Отрицание возвращаемого значения функции более полезно. – CollinD

+0

Ах, я думал, что отрицание функции a la '! IsEven' приведет к отрицанию возвращаемого значения. – giwook

+0

Я отправил ответ, который может предоставить решение. дайте мне знать, как это происходит. – CollinD

ответ

5

При обращении к функции, а не называя его, вы имеете в виду ссылки на объект работы функции:

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); }); 
}; 

Или, если вы хотите идти функциональный подход программирования, вы можете написать функцию, которая, когда называется, возвращает новой функции, которая сводит на нет возвращаемого значения:

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

Тогда в любом месте вы хотите, чтобы инвертировать значение обратного вызова, вы бы просто использовать invert:

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

Вы не можете отменить функцию. Это бессмысленно. Вместо этого вы хотите отменить возвращаемое значение функции. Я подозреваю, что вы хотите что-то вроде так

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

Почему я не могу использовать оператор ! при вызове функции (например, _.filter([1,2,3], !isEven))?

Обратите внимание, что вы на самом деле не вызывая isEven , вы просто ссылаетесь на него. Как вы сказали, !«Возвращает false, если его единственный операнд может быть преобразован в true, в противном случае возвращает значение true».

isEven - это ссылка на функцию, то есть на объект. Объекты преобразование в true, следовательно !test приводят false:

_.filter([1,2,3], false)) 

Теперь вы проезжаете логическую вместо функции _.filter, сообщение, следовательно, ошибка «тест не является функция».

Вместо этого, вы должны передать функцию, которая сводит на нет результат функции тестирования:

_.filter([1,2,3], function() { 
    return !test.apply(this, arguments); 
}); 
+1

Хороший ответ Felix –

+0

^^ (как обычно) ... –

+1

Так много похвал сегодня ... спасибо :) –