Learn JavaScript

Цикл for в JavaScript: структура, шаг, границы

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, 2
  • i <= 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 останавливает цикл.