Menu
Русский

Цикл for в JavaScript: синтаксис и примеры

Разбираем классический цикл for в JavaScript: три части заголовка, перебор массивов, операторы break и continue, вложенные циклы и типичные ошибки.

Классический цикл for в JavaScript

Когда заранее известно, сколько раз нужно повторить действие, на помощь приходит цикл for. Он удобно собирает в одной строке все три части счётного цикла: инициализацию, условие и шаг.

index.js
Output
Click Run to see the output here.

Пять итераций — пять строк вывода. Разберём заголовок цикла по частям:

  • let i = 0 выполняется один раз, до старта цикла. Здесь мы инициализируем счётчик.
  • i < 5 проверяется перед каждой итерацией. Если результат true, тело цикла выполняется. Если false — цикл завершается.
  • i++ срабатывает после каждой итерации, прямо перед тем, как условие будет проверено снова.

Эти три части разделяются точкой с запятой, а не запятой. Формально все три можно опустить, но на практике так почти никто не пишет — в таких случаях обычно берут while.

Как всё это работает вместе

Чтобы окончательно уложить порядок в голове, полезно прогнать один цикл вручную:

index.js
Output
Click Run to see the output here.

Пошагово:

  1. let i = 1 — создаём счётчик и присваиваем ему 1.
  2. Проверка i <= 3 — истина, выполняем тело. Выводим 1.
  3. Выполняется i++ — теперь i равно 2.
  4. Проверка i <= 3 — истина. Выводим 2.
  5. Выполняется i++ — теперь i равно 3.
  6. Проверка i <= 3 — истина. Выводим 3.
  7. Выполняется i++ — теперь i равно 4.
  8. Проверка i <= 3 — ложь. Выходим из цикла.

Важный момент: шаг обновления срабатывает после тела цикла, а не до. Именно здесь чаще всего и спотыкаются.

Перебор массива по индексу в javascript

Чаще всего цикл for в javascript используют именно для того, чтобы пройтись по массиву. Счётчик при этом заодно служит и индексом:

index.js
Output
Click Run to see the output here.

На что здесь стоит обратить внимание:

  • Индексация массивов начинается с нуля. Первый элемент лежит по индексу 0, последний — по length - 1.
  • В условии мы пишем i < fruits.length, а не i <= fruits.length. Со знаком <= цикл сделает лишнюю итерацию за пределами массива и выведет undefined.
  • Переменная i объявлена через let, поэтому её область видимости — только сам цикл. Снаружи её уже нет.

Если индекс вам не нужен, а важны только значения, удобнее и понятнее использовать for...of — про него будет отдельная статья.

break: досрочный выход из цикла

Оператор break мгновенно прерывает цикл. Это пригодится, когда вы уже нашли то, что искали, и нет смысла идти дальше:

index.js
Output
Click Run to see the output here.

Как только срабатывает break, управление передаётся за закрывающую скобку цикла. Шаг обновления не выполняется, условие повторно не проверяется — цикл просто завершается.

continue: пропускаем текущую итерацию

continue пропускает оставшуюся часть текущей итерации и сразу переходит к шагу обновления. Сам цикл продолжает работать — просто текущий проход до конца не доходит.

index.js
Output
Click Run to see the output here.

Чётные числа попадают на continue и проскакивают мимо console.log — печатаются только нечётные. continue удобен, когда нужно отбросить часть итераций, не заворачивая всё остальное тело цикла в if.

Шаг отличный от +1

Выражение шага — это обычное выражение, его не обязательно писать как i++. Давайте считать по двойке:

index.js
Output
Click Run to see the output here.

Count down:

index.js
Output
Click Run to see the output here.

Проход по массиву в обратном порядке — иногда это удобно, особенно когда вы удаляете элементы прямо во время итерации:

index.js
Output
Click Run to see the output here.

Что бы вы ни выбрали, правило одно: условие и шаг обновления должны работать в паре так, чтобы условие рано или поздно стало false. Иначе получите бесконечный цикл. Классический пример: for (let i = 0; i < 10; i--) — тут i уходит не в ту сторону, и цикл не завершится никогда.

Вложенный цикл for в JavaScript

Один for можно засунуть внутрь другого. При этом внутренний цикл целиком отрабатывает на каждой итерации внешнего.

index.js
Output
Click Run to see the output here.

Девять строк на выходе — три итерации внешнего цикла и по три итерации внутреннего для каждой из них. Давайте счётчикам осмысленные имена (row/col, i/j), а не пихайте везде одну и ту же переменную.

Есть один нюанс: break и continue действуют только на ближайший цикл. Выход из внутреннего цикла не останавливает внешний. Если такое поведение нужно, заведите флаг и проверяйте его во внешнем цикле, либо вынесите вложенную логику в отдельную функцию и используйте return.

Типичные ошибки

Вот на чём чаще всего спотыкаются новички:

Ошибка на единицу. Условие i <= arr.length уведёт цикл на один шаг дальше, чем нужно, а i < arr.length - 1 остановит его на шаг раньше. Канонический вариант — i < arr.length.

Забытый инкремент. Если пропустить i++ (или его аналог), счётчик не меняется и получается бесконечный цикл:

for (let i = 0; i < 10; ) {
    console.log(i); // никогда не закончится
}

Использование var для счётчика. У var область видимости — функция, поэтому счётчик «утекает» за пределы цикла и может преподнести сюрпризы в замыканиях. Используйте let.

Изменение массива во время перебора. Удаление элементов сдвигает индексы, и часть элементов вы просто пропустите. Если нужно что-то удалять — идите в обратном порядке или собирайте новый массив через filter.

Когда стоит выбрать что-то другое

Классический цикл for в javascript доступен всегда, но для типовых задач есть более короткие варианты:

  • Перебор массива javascript по значениям: for (const item of array) — чище и понятнее.
  • Преобразование массива: array.map(fn) возвращает новый массив.
  • Фильтрация: array.filter(fn).
  • Сумма или свёртка: array.reduce(fn, start).
  • Просто выполнить что-то для каждого элемента: array.forEach(fn).

Классический for берите тогда, когда реально нужен индекс, хочется прервать или пропустить итерацию посреди цикла, либо нужен нестандартный шаг — например, обратный цикл for javascript или перебор через два.

Дальше: циклы while

Цикл for javascript хорош, когда диапазон известен заранее. А когда нет — когда нужно крутиться, пока не изменится какое-то условие, — удобнее взять while и do...while. Об этом в следующей части.

Часто задаваемые вопросы

Как выглядит синтаксис цикла for в JavaScript?

В скобках через точку с запятой идут три части: for (инициализация; условие; шаг) { ... }. Инициализация выполняется один раз, условие проверяется перед каждой итерацией, а шаг — после. Типичная запись: for (let i = 0; i < 10; i++) { ... }.

Как перебрать массив циклом for?

Классика — обычный for с индексом: for (let i = 0; i < arr.length; i++) { console.log(arr[i]); }. Если индекс не нужен, удобнее for...of: for (const item of arr) { ... }. А для преобразований и фильтрации обычно лучше подходят методы массивов — map и filter.

Как работают break и continue внутри цикла for?

break сразу выходит из цикла — управление передаётся коду после него. continue пропускает остаток текущей итерации, сразу выполняет шаг и снова проверяет условие. Оба оператора работают только с ближайшим внешним циклом, если не использовать метки (labels).

Почему мой цикл for крутится бесконечно?

Скорее всего, шаг не приближает условие к false. Например, for (let i = 0; i < 10; i--) зациклится навсегда: i стартует с 0 и уходит всё дальше в минус. Проверьте, что условие и шаг работают в одну сторону и значение действительно рано или поздно выйдет за границу.

Учитесь программировать с Coddy

НАЧАТЬ