> Как пройтись по всем элементам массива в JavaScript (JavaScript)
Уровень: senior · Роль: frontend · Категория: Технические вопросы
Компании: Avito, Яндекс
Стек: JavaScript
> Пример ответа
Короткий ответ
В JavaScript есть несколько способов обойти массив: for, for...of, forEach, map, filter, reduce и другие. Выбор зависит от задачи: for даёт полный контроль, for...of удобен для итерации, forEach - для side effects, map - для трансформации, filter - для фильтрации, reduce - для агрегации. Для асинхронных операций лучше for...of с await или Promise.all.
Подробное объяснение
Все способы обхода массива в JavaScript делятся на три категории: классические циклы, методы с колбэками и итераторы.
Классические циклы:
for (let i = 0; i < arr.length; i++)- максимальный контроль, доступ к индексу, можно прервать черезbreakилиcontinuefor...of- ES6, работает с любыми iterables, удобен для чтения, можно прерватьfor...in- не рекомендуется для массивов, так как перечисляет ключи (включая унаследованные)
Методы массива с колбэками (все принимают (element, index, array)):
forEach- выполняет функцию для каждого элемента, не возвращает новый массив, не поддерживаетbreakmap- создаёт новый массив из результатов вызова функцииfilter- возвращает новый массив с элементами, прошедшими проверкуreduce- свёртка массива в одно значениеsome/every- проверяют условие, возвращают booleanfind/findIndex- ищут первый подходящий элемент или его индекс
Итераторы:
Array.prototype[Symbol.iterator]- позволяет использоватьfor...ofarr.entries(),arr.keys(),arr.values()- возвращают итераторы для пар [index, value], индексов или значений
Для асинхронного обхода:
for...ofсawait- последовательное выполнениеPromise.all(arr.map(async fn))- параллельное выполнение
На практике
Выбор способа обхода диктуется задачей и контекстом:
- Для простого перебора с side effects (логирование, запись в DOM) -
forEach - Для трансформации данных -
map - Для фильтрации -
filter - Для вычисления суммы или другого агрегата -
reduce - Для раннего выхода из цикла -
forилиfor...ofсbreak - Для асинхронных операций с ожиданием каждого -
for...ofсawait - Для параллельных асинхронных операций -
Promise.allсmap
Важно помнить про производительность: классический for быстрее методов с колбэками на больших массивах (10⁵+ элементов), но разница редко критична. Методы с колбэками создают новый контекст вызова для каждой итерации, что может быть overhead.
Пример кода
JAVASCRIPT// Классический forconst arr = [1, 2, 3];for (let i = 0; i < arr.length; i++) {console.log(arr[i]);}// for...offor (const item of arr) {console.log(item);}// forEacharr.forEach(item => console.log(item));// map - трансформацияconst doubled = arr.map(x => x * 2);// filter - фильтрацияconst evens = arr.filter(x => x % 2 === 0);// reduce - суммаconst sum = arr.reduce((acc, x) => acc + x, 0);// Асинхронный обход последовательноasync function processSequentially(items) {for (const item of items) {await asyncOperation(item);}}// Асинхронный обход параллельноasync function processParallel(items) {await Promise.all(items.map(item => asyncOperation(item)));}
Как отвечать на собеседовании
Начни с перечисления основных способов, затем уточни, что выбор зависит от задачи. Покажи понимание trade-off между производительностью, читаемостью и функциональностью. Упомяни, что for...in не подходит для массивов. Добавь про асинхронный обход - это отличает senior от junior. Если спросят про производительность, скажи, что для большинства задач разница несущественна, но для критичных участков можно использовать for.
Что проверяет интервьюер
- Знание базовых и продвинутых методов обхода
- Понимание разницы между императивным и декларативным подходом
- Умение выбирать правильный инструмент под задачу
- Понимание работы event loop и асинхронности в контексте обхода
- Осведомлённость о производительности и памяти
Типичные ошибки
- Использование
for...inдля массивов - перебирает ключи, включая прототипные - Попытка прервать
forEachчерезreturn- не работает, нужно использоватьforилиsome/every - Забывание про side effects в
map- если не нужен новый массив, используйforEach - Неправильное использование
awaitвнутриforEach-forEachне ждёт промисы, нуженfor...of - Мутация исходного массива в
map/filter- эти методы должны быть чистыми - Избыточное создание промежуточных массивов при цепочке методов - для больших данных лучше использовать
reduceилиfor
> Похожие задачи по frontend
Использовал ли Jest
Что будет если отправить запрос с пустым JSON объектом
Как обрабатывать ошибки в промисах в JavaScript?
Что происходит при вызове методов объекта, объявленных разными способами в JavaScript
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью