forEach и map: обходим и трансформируем массивы
Два самых часто используемых метода массивов. Оба принимают колбэк и проходят по каждому элементу — но делают это ради разных целей. Разберём разницу раз и навсегда.
🔄 forEach: просто пройди по каждому
Самый простой метод. Задача forEach — пройтись по каждому элементу массива и выполнить для него какое-то действие. Больше ничего: он ничего не возвращает (точнее, возвращает undefined).
Синтаксис прост: вы вызываете .forEach() на массиве и передаёте колбэк. Колбэк получит текущий элемент, его индекс и сам массив:
const fruits = ["яблоко", "банан", "вишня"];
fruits.forEach(function(fruit, index) {
console.log(`${index}: ${fruit}`);
});
// → 0: яблоко
// → 1: банан
// → 2: вишня
Параметры колбэка: первый — это элемент (обязательный), второй — индекс (необязательный), третий — сам массив (необязательный). Если индекс не нужен — просто не указывайте его:
// Чаще всего нужен только элемент
fruits.forEach(fruit => {
console.log("Фрукт: " + fruit);
});
// Важно: forEach ВСЕГДА возвращает undefined
const result = fruits.forEach(f => f.toUpperCase());
console.log(result); // → undefined
// Нельзя «сохранить результат» forEach — он для побочных эффектов!
💡 Когда использовать forEach: когда нужно что-то сделать для каждого элемента, но не нужен новый массив. Вывести в консоль, отрисовать в DOM, отправить запрос, обновить данные — всё это задачи для forEach.
🗺️ map: трансформируй и получи новый массив
map — это трансформация. Он проходит по каждому элементу, применяет к нему колбэк, и возвращает НОВЫЙ массив с результатами. Исходный массив при этом остаётся нетронутым.
Думайте о map как о «машине трансформации»: на входе один массив, на выходе — другой, такого же размера, но с изменёнными элементами.
const numbers = [1, 2, 3, 4, 5];
// map возвращает НОВЫЙ массив
const doubled = numbers.map(function(num) {
return num * 2;
});
console.log(numbers); // → [1, 2, 3, 4, 5] — исходный не изменился!
console.log(doubled); // → [2, 4, 6, 8, 10] — новый массив
// Стрелочная функция — компактный стиль
const squared = numbers.map(num => num * num);
console.log(squared); // → [1, 4, 9, 16, 25]
Обратите внимание: map всегда возвращает новый массив той же длины. Каждый элемент нового массива — это то, что вернул колбэк для соответствующего элемента исходного массива.
🔑 Ключевое правило map: колбэк должен что-то вернуть (иначе в новом массиве будут undefined). Всегда используйте return или стрелку без фигурных скобок.
👥 map с массивом объектов
В реальном коде вы очень часто будете работать с массивами объектов — например, список пользователей, полученный с сервера. map идеально подходит для извлечения нужных данных или преобразования структуры:
const users = [
{ name: "Алиса", age: 25, city: "Москва" },
{ name: "Боб", age: 30, city: "Питер" },
{ name: "Карл", age: 22, city: "Казань" }
];
// Извлечь только имена
const names = users.map(user => user.name);
console.log(names); // → ["Алиса", "Боб", "Карл"]
// Извлечь только возраст
const ages = users.map(user => user.age);
console.log(ages); // → [25, 30, 22]
// Создать строку-презентацию для каждого пользователя
const descriptions = users.map(user => {
return `${user.name} (${user.age} лет, ${user.city})`;
});
console.log(descriptions);
// → ["Алиса (25 лет, Москва)", "Боб (30 лет, Питер)", "Карл (22 лет, Казань)"]
// Трансформировать структуру объекта
const simplified = users.map(user => ({
fullInfo: `${user.name} из ${user.city}`,
isAdult: user.age >= 18
}));
// → [{ fullInfo: "Алиса из Москвы", isAdult: true }, ...]
⚠️ Частая ошибка: при возврате объекта со стрелкой нужны двойные скобки: user => ({ key: val }). Без внешних скобок JS подумает, что фигурные скобки — это тело функции, а не объект.
🆚 forEach/map vs цикл for: когда что использовать
Вопрос, который задают все новички: «Зачем forEach и map, если есть привычный for?». Давайте сравним:
🔁 Цикл for
// map через for — много кода
const nums = [1, 2, 3, 4, 5];
const result = [];
for (let i = 0; i < nums.length; i++) {
result.push(nums[i] * 2);
}
// result = [2, 4, 6, 8, 10]
Много «технического» кода: создай массив, итерируй по индексу, push. Цель (умножить на 2) теряется среди деталей.
✨ map
// То же самое через map
const nums = [1, 2, 3, 4, 5];
const result = nums.map(n => n * 2);
// result = [2, 4, 6, 8, 10]
Одна строка. Намерение очевидно: «умножь каждый элемент на 2». Код читается как описание задачи.
Когда всё же использовать for? Вот ситуации, где for лучше:
forEach нельзя прервать с break. Для этого — for или for...of.
Для очень больших массивов (миллионы элементов) for чуть быстрее. Но обычно это незаметно.
Перебирать каждый второй элемент или в обратном порядке — проще с for.
💻 Практические примеры из реального кода
🛒 Корзина покупок — подсчёт суммы через forEach
const cart = [
{ name: "Ноутбук", price: 80000, qty: 1 },
{ name: "Мышь", price: 1500, qty: 2 },
{ name: "Клавиатура", price: 3000, qty: 1 }
];
let total = 0;
cart.forEach(item => {
total += item.price * item.qty;
});
console.log(`Итого: ${total} ₽`); // → "Итого: 86000 ₽"
🌡️ Конвертация температур — классический map
const celsiusTemps = [0, 20, 37, 100];
// Celsius → Fahrenheit: F = C * 9/5 + 32
const fahrenheit = celsiusTemps.map(c => c * 9/5 + 32);
console.log(fahrenheit); // → [32, 68, 98.6, 212]
// Обратно: Fahrenheit → Celsius
const backToCelsius = fahrenheit.map(f => (f - 32) * 5/9);
console.log(backToCelsius); // → [0, 20, 37, 100]
📝 Рендер списка в React — map как основа
// В React это выглядит именно так (JSX)
const tasks = ["Купить молоко", "Позвонить маме", "Сдать проект"];
// map создаёт массив JSX-элементов
const listItems = tasks.map((task, index) => (
`${task} `
));
// В HTML:
// Купить молоко
// Позвонить маме
// Сдать проект
// map в React — это стандарт. Без него не обойтись!
🎯 Итоговое правило выбора: используйте forEach, когда вам нужно выполнить действие для каждого элемента (вывести, обновить, отправить). Используйте map, когда нужен новый массив с преобразованными данными. Если нужно сохранить результат в переменную — это map.
✅ Итоги урока
forEach— перебирает массив, вызывает колбэк для каждого элемента, возвращаетundefinedmap— перебирает массив, применяет колбэк, возвращает новый массив с результатами- Исходный массив ни
forEach, ниmapне изменяют - В колбэке map обязательно нужен
return, иначе получите массив изundefined - map идеален для трансформаций: умножить числа, извлечь поле из объектов, конвертировать единицы
- forEach — для побочных эффектов: вывод, DOM-манипуляции, обновление внешних переменных
- map — основа рендеринга списков в React и других фреймворках
В следующем уроке изучим filter, find, some и every — методы для поиска и фильтрации данных в массивах. 🔍
forEach и map
6 вопросов