Циклы while и do..while

ветвления≈ 7 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

Цикл — это способ сказать программе: повторяй, пока имеет смысл. while проверяет условие перед каждым проходом, do..while — только после первого: разница в одну строку, а поведение меняется заметно.

Разделы темы:·

Конструкция while (условие) { ... } работает так: движок смотрит на условие. Если оно истинно — выполняет тело и возвращается к условию снова. Если ложно — перешагивает через цикл и идёт дальше. Один такой круг называют итерацией.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Обратите внимание: условие проверяется до тела. Если оно ложно с самого начала, тело не выполнится ни разу — и это нормальная, рабочая ситуация, а не ошибка. Цикл с нулём итераций встречается чаще, чем кажется: например, когда обрабатывать просто нечего.

Фигурные скобки можно опустить, если тело — ровно одна инструкция: while (i < 3) i++;. Так короче, но при добавлении второй строки легко забыть вернуть скобки и получить неожиданное поведение. Пока не набита рука — пишите скобки всегда.

У do..while условие переехало вниз: do { ... } while (условие);. Тело выполняется, и только потом решается, нужен ли следующий круг. Значит, минимум один проход будет всегда, каким бы ни было условие.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Сравните с обычным while на тех же данных: он не выполнит тело ни разу, потому что проверка идёт первой.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Ситуация одна и та же: сначала надо что-то получить, и только потом мы узнаем, продолжать ли. Спросить у пользователя ввод и повторять, пока он не введёт корректное значение. Взять очередную порцию данных и остановиться, когда она окажется пустой. Во всех остальных случаях привычнее while — его читают чаще и понимают быстрее.

В скобках может стоять любое выражение, не только сравнение. Результат приводится к логическому типу: если получается true — цикл продолжается. Поэтому while (count) — законная запись: она означает «пока count не превратился в что-то ложное».

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
Значение в условииЦикл продолжится?
0нет
"" (пустая строка)нет
null, undefined, NaNнет
-1, 0.5, "0", "привет"да
[] (пустой массив)да

Последняя строка таблицы удивляет новичков: пустой массив в условии истинен. Проверять надо не сам массив, а его длину — while (arr.length). Общее правило: если сомневаетесь, пишите явное сравнение, читателю кода будет проще.

Чтобы цикл когда-нибудь закончился, что-то внутри тела должно приближать условие к ложному. Обычно это счётчик — переменная, объявленная до цикла и меняющаяся на каждой итерации. Рядом с ней часто живёт накопитель: сумма, строка или флаг, который собирает результат.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Пишите строку со счётчиком сразу, вместе со скобками цикла, и только потом заполняйте середину. Забытый i++ — ошибка номер один у всех, включая тех, кто пишет код десять лет.

Счётчик не обязан расти. Он может уменьшаться, делиться, прыгать через два — важно лишь, чтобы движение шло в сторону выхода.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Если условие никогда не станет ложным, цикл будет крутиться вечно. Чаще всего причина скучная: забыли изменить счётчик, изменили не ту переменную или поставили знак не в ту сторону: у растущего счётчика условие i > 0 вместо i < 10 истинно всегда. Браузер при этом не «ломается» — он честно исполняет то, что написано, а вкладка перестаёт отвечать, потому что JavaScript занимает единственный поток и не отдаёт его отрисовке.

Иногда бесконечный цикл пишут намеренно: while (true) плюс выход через break. Это удобно, когда условие выхода становится известно в середине тела, а не в начале.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Пока вы экспериментируете, полезен предохранитель — дополнительный счётчик с заведомо большим лимитом. Он не даст зависнуть, даже если основное условие написано неверно: цикл упрётся в лимит и остановится, а странное значение предохранителя сразу подскажет, что логика сломана.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Не перезагружайте компьютер и не ждите: страница сама не отвиснет. Откройте диспетчер задач браузера (в Chrome он в меню «Дополнительные инструменты»; в Windows и Linux открывается ещё и по Shift + Esc, а на macOS сочетания для него нет) и снимите зависшую вкладку. Остальные вкладки и несохранённые данные в них при этом не пострадают. Затем найдите в коде переменную из условия и проверьте, где именно она должна была меняться.

  • while (условие) { ... } проверяет условие перед каждой итерацией; если оно ложно сразу — тело не выполнится ни разу.
  • do { ... } while (условие); проверяет условие после тела, поэтому минимум один проход гарантирован.
  • В условии допустимо любое выражение — оно приводится к логическому типу, так что while (count) работает как while (count !== 0).
  • Чтобы цикл завершился, тело обязано двигать переменную из условия в сторону лжи: забытый счётчик — самая частая причина зависания.
  • Осознанный бесконечный цикл пишут как while (true) с выходом через break; на время экспериментов помогает счётчик-предохранитель.

1/3Что выведет код: let i = 5; while (i < 5) { console.log(i); i++; }

2/3Сколько раз выполнится тело: let i = 5; do { console.log(i); i++; } while (i < 5);

3/3Что произойдёт при выполнении: let n = 0; while (n) { n--; }

Сумма цифр числа

Дано целое положительное число. Посчитайте сумму его цифр с помощью цикла while. Подсказка: num % 10 даёт последнюю цифру, а Math.floor(num / 10) отрезает её.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Каждая итерация откусывает от числа последнюю цифру и прибавляет её к накопителю. Цикл заканчивается, когда от числа ничего не осталось — то есть когда оно стало нулём.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Здесь счётчиком служит само число: оно уменьшается в десять раз за проход и неизбежно доходит до нуля. Условие num > 0 можно записать и как while (num) — ноль ложен, результат тот же.

Первая степень двойки больше 1000

Начните с единицы и удваивайте её, пока значение не превысит 1000. Выведите получившееся число и количество удвоений.

Условие продолжения — «пока ещё не превысили», поэтому цикл останавливается ровно на первом подходящем значении.

jsлистинг · не запускается
Листинг только для чтения: этот код не запускается в браузере.

Обратите внимание на <=: со строгим < цикл остановился бы на 1024 тоже, но задача «больше 1000» на границе читается однозначнее именно так.