Функция как аргумент: forEach
Чему вы научитесь:
- передавать функцию в метод массива и отличать её от вызова функции;
- получать из массива новый массив через
mapиfilter, а одно значение — черезreduce; - искать элемент через
findи проверять условие черезsomeиevery; - сортировать числа функцией сравнения, не теряя исходный порядок.

Представьте конвейер на фабрике. По ленте один за другим едут ящики, а у ленты стоит работник. Ящик подъезжает к нему, работник делает с ним своё дело, и лента подаёт следующий. Работнику не нужно ходить по складу и считать ящики: подачу берёт на себя конвейер.
Массив и его методы устроены так же:
- массив — это лента с элементами;
- метод массива — конвейер, который сам подаёт элементы по одному;
- работника приносите вы: это функция, которую метод вызывает для каждого элемента.
До сих пор, чтобы напечатать каждый элемент массива, нужен был цикл со счётчиком, условием и индексом. Метод forEach обходит элементы сам и для каждого вызывает функцию, переданную ему аргументом:
const nums = [3, 5, 8];
function show(n) {
console.log(n);
}
nums.forEach(show);
// 3
// 5
// 8Давайте разберём пример по строкам:
const nums = [3, 5, 8];— массив из трёх чисел, наша лента.function show(n)описывает работника: он получает одно число и печатает его.nums.forEach(show)ставит работника к ленте. Метод вызываетshowтри раза: с3, с5и с8.
Счётчик, условие и индексы остаются внутри метода, и ошибиться в границах цикла негде.
Функция — тоже значение
Имя функции без скобок — это сама функция, такое же значение, как число или строка. Её можно сохранить в константе и передать в другую функцию аргументом. Скобки после имени означают вызов: show(3) выполняет тело функции прямо сейчас.
На конвейере разница видна сразу:
show— сам работник, его можно поставить к ленте;show(3)— работник уже обработал число3, и у вас в руках только результат его работы.
Функцию, которую передают аргументом, чтобы её вызвали позже, называют колбэком. Функцию, которая принимает другую функцию, называют функцией высшего порядка. В примере forEach — функция высшего порядка, а show — колбэк.
Что такое колбэк, часто спрашивают на собеседовании. Ответ укладывается в одну фразу: это функция, которую передали аргументом, чтобы её вызвал кто-то другой.
Колбэк прямо в вызове
Колбэк часто пишут прямо в вызове, стрелочной функцией. Отдельное имя ему тогда не нужно:
const words = ["red", "green"];
words.forEach((word, i) => {
console.log(i, word);
});
// 0 red
// 1 greenПри каждом вызове forEach передаёт колбэку три аргумента:
- сам элемент, здесь
word; - его индекс, здесь
i; - весь массив, который обычно не нужен.
Поэтому программа печатает 0 red, а затем 1 green. Если индекс не нужен, колбэку хватит одного параметра: лишние аргументы функция не замечает.
Колбэк вызывается по порядку, от первого элемента к последнему. Следующая строка программы выполняется только после последнего вызова.
Что возвращает forEach
forEach ничего не собирает. Он вызывает колбэк ради действия, например печати, и всегда возвращает undefined. Значение, которое вернул колбэк, пропадает:
const result = [1, 2, 3].forEach((n) => n * 2);
console.log(result); // undefinedКолбэк здесь возвращает 2, 4 и 6, но конвейер эти числа никуда не кладёт. Работник ставит на каждый ящик штамп, а коробки для готовых вещей у ленты нет.
Колбэк может менять переменную снаружи. Вызов nums.forEach((n) => { total += n; }) прибавляет каждый элемент к переменной total, объявленной через let до вызова. Так результат всё же получается, но собирать его приходится вручную.
forEach не остановить
Здесь аналогия с конвейером перестаёт работать. Настоящий работник может нажать кнопку и остановить ленту, а у forEach такой кнопки нет.
Прервать forEach на середине нельзя: break и continue внутри колбэка дают SyntaxError, и метод всегда доходит до конца массива. Когда обход нужно остановить, пишут for…of.
Частая ошибка
Функцию передали со скобками:
function show(n) {
console.log(n);
}
[1, 2].forEach(show()); // ✗TypeError: undefined is not a functionСкобки вызывают show сразу, ещё до forEach, и без аргумента, поэтому программа сначала печатает undefined. Этот вызов возвращает undefined, и forEach получает вместо функции именно это значение. Передайте имя без скобок: [1, 2].forEach(show).
Главное
forEachсам обходит массив и вызывает переданную функцию для каждого элемента.- Имя функции без скобок — сама функция, а скобки её вызывают; в метод передают имя без скобок.
- Колбэк — функция, переданная аргументом; функция высшего порядка принимает такую функцию.
forEachвсегда возвращаетundefinedи доходит до конца массива.
Подпишись, чтобы пройти курс
Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.