В JavaScript все является объектом, включая функции. Когда вы пишете выражение функции (как они вызываются) следующим образом:
const foo = function() {
console.log('This function prints this message!');
};
foo
теперь содержит ссылку на функцию, которая печатает сообщение. Мы можем назвать это так:
foo();
… который запускает код и печатает сообщение. Вы можете передавать foo
как любое другое значение, в том числе в качестве параметра для других функций. Думайте об этом как о сохранении набора инструкций для выполнения каких-либо действий: вы говорите компьютеру "foo
содержит код, который при запуске печатает сообщение."
В вашем примере выражение функции, которое вы передаете в качестве второго аргумента _.filter
объект:
function(value) {
return !test(value);
}
Вы говорите: «Передайте эту функцию, которая принимает значение, вызывает test
с ним, сводит на нет результат, и возвращает его в мою _.filter
функцию. " _.filter
знает, как вызвать эту функцию для фильтрации значений.
Программирование полно таких видов паттернов: цель не в том, чтобы взглянуть на то, что происходит, вниз, это чтобы понять, что _.filter
принимает второй параметр, это функция, которая говорит: «Если вы дадите мне значение, я скажу вам, нужно ли его сохранить». И в вашем коде вы передаете ему функцию, которая делает это, но она также вызывает другую функцию (test
), которую передал ваш пользователь. Цепочки вызовов функций могут быть длинными: сотни или тысячи функций, вызывающих другие функции.
В вашем случае, похоже, ваш код правильный. _.filter
говорит: «Дайте мне массив данных и функцию. Я вызову эту функцию для каждого значения в массиве, и он вернет мне, сохранять ли его». Вы создаете функцию, которая говорит: «Дайте мне массив данных и функцию. Я вызову эту функцию для каждого значения в массиве, и он вернет мне, если не , чтобы сохранить его. " Для этого вы просто инвертируете то, что _.filter
хочет знать: вместо того, чтобы вести запись, вы хотите знать, следует ли ее удалить.
Таким образом, ваш код дает массив пользователя и функцию до _.filter
так, как он хочет. Функция вызывается с каждым элементом массива. _.filter
хочет знать, сохранить ли предмет. Вы собираетесь позвонить test
с предметом, о котором вас спрашивает _.filter
. Но если пользовательская функция возвращает true
, мы хотим исключить элемент, а не сохранить его, поэтому мы отрицаем это (с помощью !
) и возвращаем значение. Затем вы возвращаете результат _.filter
.
Чтобы уточнить о return
: ключевое слово return
сообщает функции, вызывающей вашу функцию , что вы хотите «вернуть» , Поэтому, когда вы return !test(value)
, вы говорите , что называется вашей функцией , значением !test(value)
(в данном случае это _.filter
). Если бы вы не использовали return
, вы бы ничего не возвращали к коду, который вызывал вашу функцию. Если пользователь хочет знать, как выглядит массив после отклонения элементов, а ваша функция ничего не сделала return
, то ваша функция не очень полезна!