Циклы: while, do..while и for
Понадобилось вывести числа от 1 до 100 – копировать сто строк? Программы для того и существуют, чтобы повторять за нас. Цикл – это блок кода плюс правило «продолжать ли». Каждый повтор тела называют итерацией – или, по-русски, кругом; в уроке оба слова значат одно и то же, а «итерация» будет встречаться вам в документации и чужом коде постоянно.
Простейший – while: «пока условие истинно – выполняй тело». Как с посудой: пока в раковине есть тарелки – мой следующую. Условие проверяется перед каждым кругом.
let i = 1;while (i <= 3) { console.log(i); // без этой строки цикл никогда не закончился бы i++;}i = 1.Внимание на строку i++: тело обязано приближать конец – иначе условие никогда не станет ложным, и программа зависнет в вечном цикле. К этой ловушке вернёмся ниже отдельно.
У while есть брат do..while: он проверяет условие после тела, поэтому тело выполнится хотя бы один раз – «сначала попробуй, потом решай, пробовать ли ещё». Нужен редко, но метко.
do { console.log('хотя бы раз');} while (false);for: всё о цикле в одной строке
Весь план повторения – старт, граница, шаг – умещается в одной строке заголовка.
for (let i = 1; i <= 3; i++) { console.log(i);}Цикл «от и до» встречается так часто, что у него есть своя форма – for. В скобках через точку с запятой три части: старт (выполнится один раз перед началом), условие (проверяется перед каждым кругом), шаг (выполняется после каждого круга).
Переменная из let i = 1 живёт только внутри цикла – снаружи её нет, и это хорошо: счётчик никому не мешает. Имя i – сокращение от index: так счётчик называют со времён первых языков программирования, и любой программист узнаёт его с одного взгляда. Во вложенных циклах берут следующие буквы алфавита – j, k.
i = 1.Когда что брать? for – когда число кругов известно заранее: пройти от 1 до 100, повторить ровно десять раз. while – когда заранее неизвестно, сколько повторять: крутите, пока условие не изменится. Есть счётчик – пишите for; есть только условие – while:
let code = 7245;while (code >= 10) { // отбрасываем последнюю цифру code = Math.floor(code / 10);}console.log(code);Части заголовка можно пропускать
Любую из трёх частей можно оставить пустой – но обе точки с запятой обязаны стоять на местах. Старт пропускают, когда счётчик уже создан раньше:
let i = 1;for (; i <= 3; i++) { console.log(i);}Шаг оставляют пустым, когда переменную двигает само тело:
for (let n = 1; n < 8; ) { n *= 2; // переменную двигает тело console.log(n);}Пустыми могут быть и все три части сразу. Пустое условие считается истинным, так что for (;;) – намеренно бесконечный цикл, о них дальше:
for (;;) { // тело выполняется без конца}break: досрочный выход
break немедленно выходит из цикла целиком: остаток тела не выполняется, новые круги не начинаются, программа продолжается со строки после цикла. Работает в любом цикле – while, do..while, for. Первая типичная ситуация – поиск: нашли подходящее, дальше перебирать бессмысленно:
const secret = 4;for (let i = 1; i <= 10; i++) { if (i === secret) { console.log('найдено: ' + i); // дальше перебирать бессмысленно break; }}Вторая ситуация – цикл, задуманный без конца: условие while (true) истинно всегда, и единственная дверь наружу – break:
let timer = 5;while (true) { timer--; // единственная дверь наружу if (timer === 0) break;}console.log('старт!');continue: пропуск круга
continue мягче: он пропускает остаток текущего круга и переходит к следующему. Цикл не останавливается – просто один круг закончился досрочно. В for шаг при этом выполняется как обычно.
Главный сценарий – фильтрация: обработать только подходящие элементы. Условие с continue в начале тела читается как охранник на входе: «этот не подходит – следующий», а весь код ниже остаётся ровным, без лишней вложенности.
for (let i = 1; i <= 6; i++) { // нечётное – пропускаем круг if (i % 2 !== 0) continue; console.log(i);}for (let i = 1; i <= 4; i++) { // выпадает только тройка if (i === 3) continue; console.log(i);}console.log('готово');Бесконечные циклы
Цикл бесконечен, когда условие никогда не становится ложным. Чаще всего это ошибка: забыли i++, двинули не ту переменную или написали условие, которое не зависит от тела. Программа не падает – она молча работает без конца, и вкладка браузера виснет.
Но бесконечный цикл бывает и намеренным: while (true) или for (;;) пишут, когда число кругов заранее неизвестно, а из цикла выходят изнутри через уже знакомый break.
let thickness = 0.1; // лист бумаги, ммlet folds = 0;while (true) { thickness *= 2; // сложили пополам folds++; // толще человеческого роста if (thickness > 1700) break;}// 15 – а не «семь раз», как в известном мифеconsole.log(folds);let i = 1;while (i <= 3) { // i не меняется – условие истинно всегда console.log(i);}// теперь вы знаете
- while повторяет, пока условие истинно; do..while проверяет после тела
- for – когда число кругов известно заранее; while – когда есть только условие
- for собирает старт, условие и шаг в одной строке; любую часть можно оставить пустой
- break выходит из цикла целиком – поиск и выход из бесконечных
- continue пропускает остаток круга – фильтрация без вложенности
- for (;;) и while (true) – намеренно бесконечные циклы с выходом через break
- Бесконечный цикл по ошибке – условие, в котором ничего не меняется
Сколько строк напечатает код?
let n = 100;do {console.log(n);n++;} while (n < 10);
Сколько строк напечатает цикл?
for (let i = 0; i < 5; i += 2) {console.log(i);}
Что делает запись for (;;) { ... }?