JavaScript - это язык программирования, поддерживающий первоклассные функции. Это означает, что вы можете рассматривать функции как объекты в вашем коде - переменные.
В приведенном выше фрагменте console.log
получает и правильно понимает, что он получил ссылку на функцию с именем foo
, и выводит красивое объяснение этого.
Объявление функции вверху сделало нас переменной, названной так же, как функция, которая содержит ссылку на саму функцию. Вы можете обращаться с этой переменной так же, как с любой другой.
Приведенный выше код сначала показывает нам поведение функции по умолчанию. Вы можете передать ссылку или позвонить. После этого мы присваиваем номер 1 переменной foo
, затем мы потеряли ссылку на функцию, поэтому вы больше не можете вызывать foo()
.
Обратные вызовы
Когда функции передаются как аргументы, они называются обратными вызовами. Функции, которые принимают обратные вызовы, называются функциями высокого порядка (HOF). Позже в этой серии мы увидим другой тип HOF, а пока давайте поработаем с обратными вызовами.
Одна довольно распространенная функция в JavaScript - это setTimeout
, которая принимает обратный вызов и время (в миллисекундах), после чего ожидает это количество времени перед запуском обратного вызова.
Используя синтаксис стрелочной функции ES6 наш код мог бы выглядеть так:
Обе версии используют синтаксис выражения функции. Вы также можете передать имя функции в качестве обратного вызова.
Обратите внимание: мы передаем ссылку на функцию myLog, а не вызов функции!
Приведенный выше код немедленно регистрирует текст, поскольку, когда вы используете круглые скобки после имени функции, вы ее вызываете. Наш setTimeout
ничего не получит в качестве обратного вызова (поскольку myLog
ничего не возвращает).
Создание собственного HOF
- Дважды
Начнем с простого. Предположим, вы хотите применить функцию дважды к одному и тому же значению.
Мы просто дважды закодировали функцию, которая принимает обратный вызов с именем fn
и значение, а затем дважды применяет наш обратный вызов.
2. Для каждого
Другой распространенный сценарий - перебор массива. Вы бы сделали что-то вроде этого:
Мы можем написать функцию, чтобы сделать наш цикл более читаемым и многоразовым.
Вы также можете узнать индекс текущего элемента. Давайте поместим это в наш обратный вызов:
Но в JavaScript уже есть Array#forEach
метод, поэтому мы можем:
Вы можете заметить, что Array#forEach
передаёт сам массив в качестве третьего параметра. Мы можем игнорировать это так:
Обзор
- Ссылки на функции хранятся в переменных.
- Вы можете передавать ссылки на функции в качестве аргументов другой функции.
- Функции, передаваемые в качестве аргументов, называются обратным вызовом.
- Функции, которые принимают обратные вызовы, называются функциями высшего порядка.