Циклы в JavaScript: перебор массивов и примеры
К чему пригодится эта статья
- Быстро вспомнить синтаксис циклов в JavaScript.
- Понять, когда использовать тот или иной цикл.
- Получить чек-листы, шпаргалку и практические советы для разработки и тестирования.
Инкрементный и декрементный for
Инкрементный цикл for — это базовый способ итерации в JavaScript. Он задаёт начальное значение, проверяет условие и изменяет счётчик с помощью ++ или –.
Общий шаблон выглядит так:
for(var i = initial value; i < array.length; i++) {
array[i]}
Пройдем через пример перебора массива, используя приведённый шаблон:
anArray = [1, 3, 5, 6];
for(let i = 0; i < anArray.length; i++) {
console.log(anArray[i])
}
Вывод:
1
3
5
6 Операция над каждым элементом в цикле for:
anArray = [1, 3, 5, 6];
for(let i = 0; i < anArray.length; i++) {
console.log("5", "x", anArray[i], "=", anArray[i] * 5)
}
Вывод:
5 x 1 = 5
5 x 3 = 15
5 x 5 = 25
5 x 6 = 30
Цикл выше идёт по массиву вперед (инкремент). Чтобы получить обратный порядок, используйте декремент с оператором –. Синтаксис похож, но счётчик стартует с anArray.length - 1 и уменьшается до 0:
anArray = [1, 3, 5, 6];
for(let i = anArray.length-1; i > = 0; i--) {
console.log("5", "x", anArray[i], "=", anArray[i]*5)
}
Вывод:
5 x 6 = 30
5 x 5 = 25
5 x 3 = 15
5 x 1 = 5Пояснение: индекс массива начинается с нуля, поэтому последний индекс = length - 1. Условие i >= 0 заставляет цикл корректно закончиться на нулевом индексе.
Связанные материалы: методы массивов JavaScript, которые стоит освоить.
forEach
Метод array.forEach удобен и короче, чем «сырые» циклы for. Он перебирает элементы поочередно, но не позволяет проходить массив в обратном порядке напрямую (нет доступа к предшествующему элементу в «памяти» цикла).
Общий шаблон:
array.forEach(element => {
action
})Пример вывода значений:
let anArray = [1, 3, 5, 6];
anArray.forEach(x => {
console.log(x)
});
Вывод:
1
3
5
6
Пример математической операции для каждого элемента:
let anArray = [1, 3, 5, 6];
anArray.forEach(x => {
console.log("5", "x", x, "=", x * 5)
});
Вывод:
5 x 1 = 5
5 x 3 = 15
5 x 5 = 25
5 x 6 = 30
for…in
Цикл for…in проходит по индексам (ключам) массива. Он возвращает индексы, а не значения элементов.
Общий шаблон:
for (let element in array){
action
}Пример вывода индексов:
let anArray = [1, 3, 5, 6];
for (let i in anArray){
console.log(i)
}
Вывод:
0
1
2
3
Чтобы вывести сами значения, обращайтесь к элементу по индексу:
let anArray = [1, 3, 5, 6];
for (let i in anArray){
console.log(anArray[i])
}
Вывод:
1
3
5
6
Пример обхода в обратном порядке: сначала создаём вспомогательную переменную v = length - 1, а затем уменьшаем её внутри цикла:
let anArray = [1, 3, 5, 6];
// Remove one from the length of the array and assign this to a variable:
let v = anArray.length - 1;
// Use the above variable as an index basis while iterating down the array:
for (let i in anArray){
console.log(anArray[v])
v -=1;
}
Вывод:
6
5
3
1
Этот приём похож на декрементный for, но код получается более явным и читабельным.
for…of
Цикл for…of итерирует не по индексам, а по самим элементам массива. Его часто используют, когда индекс не нужен.
Общий шаблон:
for (let i of array) {
action
}
Пример простого вывода:
let anArray = [1, 3, 5, 6];
for (let i of anArray) {
console.log(i)
}
Вывод:
1
3
5
6
Обход в обратном порядке аналогичен примеру с for…in: используйте вспомогательное значение v = length - 1 и уменьшайте его внутри цикла:
let anArray = [1, 3, 5, 6];
let v = anArray.length - 1;
for (let x of anArray) {
console.log(anArray[v])
v -=1;
}
Вывод:
6
5
3
1
Операция над элементами при обратном обходе:
let anArray = [1, 3, 5, 6];
let v = anArray.length - 1;
for (let x of anArray) {
console.log("5", "x", anArray[v], "=", anArray[v] * 5)
v -=1;
}
Вывод:
5 x 6 = 30
5 x 5 = 25
5 x 3 = 15
5 x 1 = 5
while
Цикл while выполняется, пока указанное условие истинно. При ошибочной логике можно получить бесконечный цикл.
Пример потенциально бесконечного цикла (i всегда меньше 10):
let i = 0;
while (i < 10) {
console.log(4)
}Пример корректного прохода по массиву:
let i = 0;
while (i < anArray.length) {
console.log(anArray[i])
i +=1
}
Вывод:
1
3
5
6
do…while
Цикл do…while сначала выполняет тело (блок do), а затем проверяет условие в while. Тело гарантированно выполнится хотя бы один раз.
Шаблон:
do{
actions
}
while (
consition
)Пример итерации по массиву:
do{
console.log(anArray[i])
i +=1
}
while (
i < anArray.length
)
Вывод:
1
3
5
6
Важные замечания
Важно:
- Выбирайте for, если нужен индекс и произвольный доступ к элементам.
- forEach удобен для простых последовательных операций и более декларативен.
- for…in подходит для перебора ключей объектов, а не для массивов с нестандартными свойствами.
- for…of — простой способ работать с элементами, не считая индексы.
- while и do…while дают гибкость, но требуют аккуратности, чтобы не упустить шаг инкремента/декремента.
Когда тот или иной цикл не подходит (контрпримеры)
- forEach не позволяет прервать цикл через break или return из внешней функции — это ограничивает его в задачах, где нужно досрочно выйти.
- for…in итерация по массиву может неожиданно пройти по унаследованным ключам, если в прототип добавлены свойства.
- while удобен для условной итерации, но легко превратить программу в бесконечный цикл при ошибке счётчика.
Альтернативные подходы
- Используйте методы массива map/filter/reduce для функциональной обработки и преобразования данных.
- Для асинхронных последовательных операций применяйте for…of с await внутри (работает последовательно).
- Если нужна высокая производительность для больших массивов, учитывайте простые for-циклы и избегайте лишних вызовов функций в теле.
Ментальные модели и эвристики
- Если нужен индекс — используй for.
- Если нужен только элемент — используй for…of.
- Если нужен декларативный трансформ — используй map или reduce.
- Если требуется прерывание — используйте for/for…of/while, не forEach.
Чек-лист для ролей
Разработчик:
- Нужен ли индекс? Если да — for.
- Требуется ли досрочный выход? Если да — не forEach.
- Оцените читаемость для команды.
Тестировщик:
- Покрыты ли граничные значения (пустой массив, один элемент)?
- Есть ли риск бесконечного цикла?
- Проверены ли варианты с изменением массива в процессе итерации?
Архитектор:
- Соответствует ли выбор циклов политике проекта по стилю.
- Есть ли предпочтение функционального стиля (map/reduce) для предсказуемости.
Шпаргалка: короткие шаблоны
- Простой проход с индексом:
for (let i = 0; i < arr.length; i++) {
// доступ: arr[i]
}- Проход по элементам:
for (let x of arr) {
// x — текущий элемент
}- Для функций с побочными эффектами:
arr.forEach(x => console.log(x))- Асинхронная последовательная обработка:
for (let item of arr) {
await doAsync(item)
}Примеры тест-кейсов и критерии приёмки
- Пустой массив: цикл не должен выбрасывать ошибку, результат — отсутствие итераций.
- Одно значение: одна итерация, корректный вывод.
- Массив с разными типами: обработка не должна приводить к исключениям (если это требование).
- Изменение длины массива в теле цикла: явно документировать поведение и протестировать.
Критерии приёмки:
- Все базовые сценарии (пустой, единичный, несколько элементов) проходят.
- Нет бесконечных циклов.
- Код читабелен и соответствует стандартам команды.
Мини-методология выбора цикла
- Определите, нужен ли индекс.
- Решите, нужно ли прерывать итерацию досрочно.
- Оцените читаемость и потенциальные побочные эффекты.
- Выберите for, for…of, forEach или функциональные методы.
Диаграмма принятия решения (Mermaid)
flowchart TD
A[Нужен индекс?] -->|Да| B[Использовать for]
A -->|Нет| C[Нужен досрочный выход?]
C -->|Да| B
C -->|Нет| D[for...of или forEach]
D --> E{Есть асинхронность?}
E -->|Да| F[for...of + await]
E -->|Нет| G[forEach или for...of]Советы по безопасности и производительности
- Не модифицируйте массив, по которому идёт итерация, если этого можно избежать. Это снижает предсказуемость.
- Для больших массивов избегайте частых аллокаций внутри тела цикла.
- В hot-path используйте простые for-циклы и минимизируйте вызовы функций.
Локальные примеры и подводные камни
- Если ваш код исполняется в окружении с расширениями прототипов (редко, но возможно), используйте Object.hasOwnProperty внутри for…in или избегайте for…in для массивов.
- Для международных приложений учитывайте, что порядок итерации важен при рендеринге элементов UI.
Резюме
Циклы — основа перебора массивов в JavaScript. Выбор между for, forEach, for…in, for…of, while и do…while зависит от задачи: нужен ли индекс, требуется ли возможность прерывания, нужна ли асинхронность. Следуйте чек-листу, тестируйте граничные случаи и отдавайте предпочтение понятному и производительному варианту для вашей команды.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone