С массивами в JavaScript можно делать много всего полезного: фильтровать, изменять, сортировать и анализировать. Но чаще всего сначала для этого нужно перебрать каждый элемент. Для этого есть несколько способов, и один из самых удобных — метод forEach(). Он позволяет пройтись по каждому элементу массива и выполнить какое-то действие: вывести в консоль, изменить данные, отправить запрос или что-то ещё.
В этой статье разберём, как работает forEach(), когда он полезен, а когда лучше выбрать map(), или reduce()filter(). А ещё посмотрим реальные примеры использования и сравним с классическим for.
Введение в forEach()
Метод forEach() позволяет пройтись по каждому элементу массива и выполнить для него заданное действие, переданное в функции-колбэке.
👉 Колбэк (callback) — это когда мы вызываем что-то, например функцию, она что-то делает, возвращает результат, и этот результат мы тут же используем.
Чаще всего в качестве колбэка используют стрелочные функции, так как они короче и удобнее.
Вот как выглядит самый простой пример колбэка. Допустим, мы хотим последовательно вывести в консоль каждый элемент массива — тогда пишем так:
const numbers = [10, 20, 30];
numbers.forEach(num => console.log(`Число: ${num}`));

Здесь всё просто: мы берём массив numbers и шаг за шагом вытаскиваем каждый его элемент num, чтобы вывести его на экран.
Синтаксис и параметры
Под капотом метод forEach() работает так: он перебирает элементы массива и выполняет переданную в него функцию. Эта функция-колбэк получает три параметра: сам элемент, его индекс и весь массив.
array.forEach(callback(element, index, array), thisArg);
Передать можно следующие параметры:
callback— функция, которая выполняется для каждого элемента массива;element— текущий элемент массива;index(необязательно) — индекс текущего элемента;array(необязательно) — сам массив, по которому мы проходимся;thisArg(необязательно) — значение, которое будет использоваться как this внутри функции-колбэка.
Возвращаемое значение
Метод forEach() не возвращает новый массив или какое-либо значение. Он просто выполняет переданную функцию для каждого элемента массива и всегда возвращает undefined.
const result = [1, 2, 3].forEach(num => console.log(num));
console.log(result); // undefined

Мы перебираем массив [1, 2, 3] и выполняем console.log(num) для каждого элемента. В консоли появляются 1 2 3. После завершения forEach() не возвращает результат, и result становится undefined — это значит, что колбэку больше нечего вам отдать.
Примеры использования forEach()
Дальше посмотрим самые распространённые примеры использования этого метода.
Пример 1: перебор массива
Самый простой вариант. Например, у нас есть массив с видами спорта, и мы просто хотим вывести каждый из них на экран, ничего больше с этим не делая:
const sports = ["Футбол", "Баскетбол", "Теннис", "Плавание", "Бокс"];
sports.forEach(sport => {
console.log(` ${sport}`);
});
В этом коде:
- метод
forEach()перебирает массив sports; sport— текущий элемент массива, который передаётся в колбэк-функцию.

Такой способ удобен, когда нужно просто выполнить действие для каждого элемента — вывести данные в консоль, обновить интерфейс или записать информацию в лог. Также forEach() часто используется при рендеринге списков в веб-приложениях, когда нужно отобразить каждый элемент массива на странице.
Пример 2: использование аргумента текущего элемента
Допустим, мы разрабатываем веб-приложение и у нас есть массив с названиями товаров. Мы хотим сгенерировать HTML-разметку для списка этих товаров.
const products = ["Ноутбук", "Смартфон", "Наушники", "Часы"];
products.forEach(product => {
// Создаём элемент списка
const item = document.createElement("li");
// Добавляем текст с названием товара
item.textContent = `${product}`;
// Добавляем в список на странице
document.getElementById("product-list").appendChild(item); });
Здесь произошло вот что:
forEach()перебирает массивproducts, передавая в функцию каждый товар;product— текущий элемент массива, его значение используется для создания текста в<li>;- для каждого товара создаётся новый
<li>, который добавляется в список сid=”product-list”.
В итоге в готовой HTML-разметке, которую получит браузер, это будет выглядеть так:
<ul id="product-list">
<li>Ноутбук</li>
<li>Смартфон</li>
<li>Наушники</li>
<li>Часы</li>
</ul>
Такой способ часто используется для динамического рендеринга списков в веб-приложениях — при загрузке товаров в интернет-магазине, отображении пользователей в чате или создании списка задач в планировщике.
Пример 3: использование индекса
У нас много проектов (ха-ха), поэтому на этот раз мы делаем дашборд со статистикой продаж и хотим вывести в консоль данные о каждом заказе, добавляя его номер. Для этого мы перебираем массив и используем индексы для вывода данных:
const orders = [1523, 1628, 1745, 1890];
orders.forEach((order, index) => {
console.log(`Заказ #${index + 1}: ID ${order}`);
});

Такой способ удобен, когда нужно пронумеровать данные и вывести их в понятном виде. Подходит для обработки списка заказов, обращений в поддержку или логов серверных запросов.
Пример 4: использование массива
У нас есть массив с именами ацтекских богов и их сферами влияния (почему бы и нет?). С помощью forEach() мы проходимся по массиву и выводим информацию о каждом боге, учитывая их общее количество.
const gods = [
{ name: "Тескатлипока", domain: "Ночь и судьба" },
{ name: "Кетцалькоатль", domain: "Ветер и мудрость" },
{ name: "Уицилопочтли", domain: "Война и солнце" },
{ name: "Тлалок", domain: "Дождь и земледелие" }
];
gods.forEach((god, index, arr) => {
console.log(`Бог №${index + 1}/${arr.length}: ${god.name} — ${god.domain}`);
});
Здесь на вход мы передаём 3 параметра:
god— объект с именем и сферой влияния;index— порядковый номер бога, используемindex + 1, чтобы счёт начинался с 1;arr.length— показывает общее количество богов, то есть используем его напрямую, чтобы показать, сколько всего элементов.

Такой подход удобен, когда данные хранятся в объектах и нужно использовать сразу несколько значений. Также он полезен, если важно знать общее количество элементов в массиве, например при создании статистики или отображении прогресса.
Пример 5: условные операторы в функции обратного вызова
Наконец, у нас есть массив чисел, и мы хотим вывести только чётные. Для этого нам нужно перебрать массив, потом проверить каждое число с помощью условия и вывести в консоль только чётные числа, а для нечётных добавить другое сообщение.
Сделаем так:
const numbers = [12, 7, 24, 31, 46, 53, 60];
numbers.forEach(num => {
if (num % 2 === 0) {
console.log(`Чётное число: ${num}`);
} else {
console.log(`Нечётное число: ${num}`);
}
});
Здесь мы перебрали в массиве numbers каждое число num, проверили каждое из них на чётность и через условие вывели сообщение.

Это можно использовать при фильтрации списка товаров в интернет-магазине, где можно выделить только доступные позиции. Или при разделении пользователей на активных и заблокированных в панели администратора. Также такой подход помогает анализировать данные, например определять, какие формы были заполнены корректно, а какие содержат ошибки.
Сравнение forEach() с циклом for
До появления forEach() в 2009 году разработчики использовали старый добрый цикл for, который позволял перебрать массив с явным управлением индексами. Но forEach() сильно всё упростил, сделав код лаконичнее.
При этом forEach() не заменяет полностью for — есть ситуации, когда лучше использовать именно for. Например, когда нужно прервать выполнение цикла, пропустить отдельные итерации или обработать пропущенные элементы массива. Дальше разберёмся подробнее.
Преимущества и недостатки
Метод forEach() делает код более лаконичным и читаемым. Не нужно вводить индексную переменную, писать громоздкие конструкции и вручную управлять индексами, что может вызвать ошибки:
// forEach()
const users = ["Михаил", "Инна", "Игорь"];
users.forEach(user => console.log(`Привет, ${user}!`));

Метод forEach() удобен на фронтенде, когда надо пройтись по HTML-элементам и, например, одним действием навесить обработчики событий сразу на несколько кнопок:
document.querySelectorAll(".button").forEach(button => {
button.addEventListener("click", () => alert("Клик!"));
});
При этом у forEach() есть свои недостатки:
- Нельзя прервать выполнение. В
forEach()не работаютbreakиcontinue, цикл всегда дойдёт до конца. Вforможно легко остановить выполнение или пропустить элементы. - Чуть медленнее for. В
forEach()создаётся функция-колбэк, что даёт небольшую нагрузку. В обычномforбез лишних функций обработка может быть быстрее. - Не подходит для обработки пропущенных элементов. В
forEach()пустые места массива просто игнорируются, тогда какforих учитывает и позволяет работать сundefined.
Посмотрим на примерах.
Допустим, по условию нам нужно дойти до какого-то определённого элемента и закончить выполнение. Как выйти из forEach()? А никак: он всегда перебирает весь массив до конца.
Если нужно прервать выполнение, тогда лучше использовать for, где можно явно прописать инструкцию break, которая прерывает цикл:
const numbers = [1, 2, 3, 4, 5];
for (let i = 0; i < numbers.length; i++) {
if (numbers[i] === 3) {
break; // цикл останавливается до вывода 3
}
console.log(numbers[i]);
}

В JavaScript массив может содержать пустые элементы. Так бывает, когда элементы удаляются в процессе работы или массив создаётся с указанием длины, но без явного заполнения значений.
const array = [1, , 3, , 5]; // Два пропущенных элемента
Разреженные массивы могут вести себя непредсказуемо при переборе, потому что forEach() пропускает пустые элементы, а вот for видит их как undefined — и с этим уже можно работать.
Метод forEach() справляется с этим так:
array.forEach(num => console.log(num)); // 1 3 5

То есть он просто игнорирует пропущенные элементы.
А вот как с разреженным массивом работает for:
for (let i = 0; i < array.length; i++) {
console.log(array[i]);
}

Каждый пропущенный элемент в массиве фактически представляет собой undefined. Если, например, массив содержит данные о заказах, но в некоторых местах информации нет, такие пропуски можно заменить на более осмысленные значения, например “Неизвестно” или 0. Это поможет сделать вывод более понятным и избежать ошибок при обработке данных.
Особенности работы forEach()
Метод forEach() удобен, когда нужно просто выполнить действие для каждого элемента массива. Но он не возвращает новый массив и не позволяет прервать выполнение, что отличает его от других методов перебора. В некоторых случаях другие методы — map(), filter() или reduce() — могут быть более подходящими.
Отличия от других методов перебора массивов
Кроме forEach() в JavaScript есть другие способы перебора массивов:
map()возвращает новый массив, в котором каждый элемент преобразован по заданному правилу;filter()создаёт новый массив, содержащий только те элементы, которые удовлетворяют условию;reduce()используется, когда нужно получить одно итоговое значение (например, сумму или среднее).
Разберём на примерах.
👉 Метод map() создаёт новый массив, поэтому если нам нужно преобразовать массив и сохранить изменения, то используем map():
const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6]

Здесь мы взяли исходный массив numbers, умножили каждый элемент массива на 2 и записали результат в новый массив doubled. Если в таком коде заменить map() на forEach(), новый массив не создастся, потому что forEach() ничего не возвращает:

👉 Метод filter() отбирает нужные элементы. Когда нужно отфильтровать массив по какому-то параметру и сохранить результат в новый массив, используем filter():
const numbers = [1, 2, 3, 4, 5];
const evens = numbers.filter(num => num % 2 === 0);
console.log(evens); // [2, 4]

При этом в forEach() можно сделать фильтрацию по условию, но результат не сохранится, то есть исходный массив никак не изменится.
👉 Метод reduce() собирает итоговое значение. Его используют, когда нужно подсчитать сумму, найти максимум или агрегировать данные. Для этого в колбэк-функцию reduce() передаётся аккумулятор (acc), который накапливает результат вычислений по мере перебора массива:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15

Использование thisArg
В методе forEach() можно передать второй аргумент — thisArg. Он определяет, каким будет this внутри колбэк-функции. Это полезно, если forEach() вызывается внутри метода объекта и нам нужно, чтобы this внутри функции оставался привязанным к этому объекту.
Но в современном коде его чаще заменяют стрелочными функциями, где this автоматически берётся из внешнего контекста. Поэтому передача thisArg актуальна, только если используется обычная функция, например:
- В старом коде, где нет стрелочных функций.
- Если нужно явно передать контекст (
this), например в динамических сценариях. - Если код должен работать в средах, где стрелочные функции не поддерживаются (очень редко).
Допустим, есть объект user, который содержит prefix и метод logNames(). Этот метод принимает массив имён и должен вывести их с заданным префиксом.
Если внутри forEach() использовать обычную функцию, this по умолчанию потеряет связь с объектом user, и this.prefix окажется undefined. Чтобы этого не произошло, передаём this вторым аргументом в forEach() и сохраняем нужный контекст.
const user = {
prefix: "👤",
logNames(names) {
names.forEach(function(name) {
console.log(this.prefix, name);
}, this); // Передаём thisArg, чтобы сохранить контекст
}
};
user.logNames(["Михаил", "Инна", "Игорь"]);

Но лучше использовать стрелочную функцию, которая автоматически берёт this из внешнего контекста:
const user = {
prefix: "👤",
logNames(names) {
names.forEach(name => {
console.log(this.prefix, name); // `this` берётся из метода logNames
});
}
};
user.logNames(["Михаил", "Инна", "Игорь"]);



