for - самый универсальный цикл в JavaScript. Он удобен, когда заранее известны границы повторений или нужен индекс (например, при работе с массивами).
Базовая структура for
Синтаксис выглядит так:
for (init; condition; step) {
// тело цикла
}
Цикл состоит из трех частей:
- init (инициализация) - выполняется один раз перед стартом цикла
- condition (условие) - проверяется перед каждой итерацией; если
false, цикл останавливается - step (шаг) - выполняется после каждой итерации
Простой пример:
for (let i = 0; i < 3; i += 1) {
console.log(i);
}
// 0
// 1
// 2
Разбор частей: init, condition, step
Инициализация (init)
Чаще всего здесь объявляется счетчик:
for (let i = 0; i < 5; i += 1) {
// ...
}
Обычно используется let, потому что счетчик меняется. Область видимости i ограничена циклом.
for (let i = 0; i < 1; i += 1) {}
// console.log(i); // ReferenceError
Условие (condition)
Условие определяет границу, когда цикл должен остановиться.
for (let i = 1; i <= 3; i += 1) {
console.log(i);
}
// 1 2 3
Разница между < и <= важна:
i < 3- итерации для 0, 1, 2i <= 3- итерации для 0, 1, 2, 3
Шаг (step)
Шаг задает, как меняется счетчик после каждой итерации.
Частые варианты:
i += 1; // увеличить на 1
i -= 1; // уменьшить на 1
i += 2; // увеличить на 2
Короткая форма i++ тоже работает, но i += 1 обычно проще читать, особенно в учебных примерах.
Границы и работа с массивами
Классическая задача - пройти по массиву по индексам. Главная граница здесь - arr.length.
const items = ["a", "b", "c"];
for (let i = 0; i < items.length; i += 1) {
console.log(i, items[i]);
}
// 0 "a"
// 1 "b"
// 2 "c"
Важно: индексы массива начинаются с 0, а последний индекс равен length - 1. Поэтому условие обычно i < items.length, а не i <= items.length.
Неверно (в конце будет undefined):
const items = ["a", "b", "c"];
for (let i = 0; i <= items.length; i += 1) {
console.log(items[i]);
}
// "a", "b", "c", undefined
Цикл в обратную сторону
Иногда нужно идти от конца к началу (например, при удалении элементов по условию).
const items = ["a", "b", "c"];
for (let i = items.length - 1; i >= 0; i -= 1) {
console.log(i, items[i]);
}
// 2 "c"
// 1 "b"
// 0 "a"
Пропуск итерации и остановка: continue и break
continue
continue пропускает оставшуюся часть текущей итерации и переходит к следующей.
for (let i = 0; i < 5; i += 1) {
if (i === 2) continue;
console.log(i);
}
// 0 1 3 4
break
break полностью завершает цикл.
for (let i = 0; i < 5; i += 1) {
if (i === 3) break;
console.log(i);
}
// 0 1 2
Варианты записи for
Любая часть может быть пустой
Если счетчик уже объявлен, init можно оставить пустым:
let i = 0;
for (; i < 3; i += 1) {
console.log(i);
}
Если шаг задается внутри тела, step можно убрать:
for (let i = 0; i < 3; ) {
console.log(i);
i += 1;
}
Если убрать условие, цикл станет бесконечным, поэтому обычно используют break:
let i = 0;
for (;;) {
if (i >= 3) break;
console.log(i);
i += 1;
}
Частые ошибки
1) Ошибка границы (off-by-one)
Часто проявляется как лишняя итерация или пропуск последнего элемента. При работе с массивом почти всегда правильно i < arr.length.
2) Счетчик не меняется
Если забыть i += 1, цикл может стать бесконечным.
3) Изменение длины массива во время прохода
Если в цикле добавлять/удалять элементы, границы length могут меняться. В таких случаях лучше заранее сохранить длину или проходить массив с конца.
const items = ["a", "b", "c"];
const len = items.length;
for (let i = 0; i < len; i += 1) {
console.log(items[i]);
}
Что стоит запомнить
- for подходит, когда нужны четкие границы и индекс.
- В
for (init; condition; step)условие проверяется перед каждой итерацией. - Для массива обычно используется
i < arr.length, а не<=. continueпропускает итерацию,breakостанавливает цикл.