Когда заранее неизвестно, сколько будет итераций
Цикл for хорош, когда диапазон известен заранее — «сделай это 10 раз», «пройдись по всем индексам массива». А вот цикл while в JavaScript нужен для другой ситуации: крутись, пока что-то не изменится. Сколько будет итераций — неизвестно, известно лишь условие, при котором пора остановиться.
Синтаксис предельно простой:
JavaScript проверяет условие в скобках. Если оно истинно — выполняется блок. Потом условие проверяется снова, и снова, и так до тех пор, пока не станет ложным. Забудете про count++ — условие никогда не изменится, и вот вам бесконечный цикл.
Как думать про цикл while: проверь, выполни, повтори
Чтобы цикл while в javascript работал осмысленно, должны совпасть три вещи:
- Есть что-то, от чего зависит условие.
- Тело цикла как-то меняет это «что-то».
- Рано или поздно условие становится ложным.
Упустите любой пункт — и начинаются проблемы. Классический баг — забыть про второй шаг:
let count = 0;
while (count < 5) {
console.log(count);
// забыли увеличить count — цикл будет бесконечным
}
Такое будет крутиться, пока ты сам не прибьёшь процесс. А если это случится на сервере — жди беды. Всегда задавай себе вопрос: что именно в теле цикла сделает условие ложным?
Реальный сценарий: когда заранее не знаешь, где остановиться
Вот тут while как раз обходит for. Ты разгребаешь элементы откуда-то и понятия не имеешь, сколько их там, — пока не вычерпаешь всё до конца:
shift() убирает и возвращает первый элемент массива. Цикл крутится, пока в очереди что-то есть, и сам останавливается, когда она опустеет. То же самое можно написать через for, но получится борьба с природой задачи — while куда точнее передаёт намерение.
do...while в JavaScript: сначала делаем, потом проверяем
do...while меняет порядок на противоположный: сначала выполняется тело, а потом проверяется условие. Благодаря этому одна итерация гарантированно произойдёт:
Тело выполнится хотя бы раз — даже если условие ложно с самого начала. В обычном while всё иначе: если условие ложно сразу, цикл не отработает ни одного раза.
Типичный пример — запросить что-то у пользователя, проверить введённое значение и спросить заново, если ответ не подходит. Спрашивать надо хотя бы один раз, поэтому тут как раз в тему do...while.
Обратите внимание на точку с запятой после закрывающей ) — в отличие от while и for, в do...while она обязательна.
break: досрочный выход из цикла
break сразу же прерывает ближайший цикл. Это способ прервать выполнение, когда обычного условия выхода недостаточно:
После срабатывания break цикл тут же прекращается — ни остаток тела, ни повторная проверка условия уже не выполняются. Вы вышли.
while (true) с break
Иногда условие выхода удобнее описать внутри тела цикла, а не в его заголовке. В таком случае переверните логику: запускайте бесконечный цикл и выходите из него через break, когда нужно.
Два выхода: по успеху и по предохранительному лимиту. И вот этот лимит — штука важная. while (true) без гарантированного пути к break — это бомба замедленного действия, она же бесконечный цикл javascript.
continue: переход к следующей итерации
continue перекидывает управление сразу к проверке условия, пропуская остаток тела текущей итерации:
Один подводный камень: если то, что продвигает цикл вперёд, стоит после continue, вы только что получили бесконечный цикл. В примере выше n++ идёт до continue, так что всё ок. Переставьте его после — и n навсегда застрянет на чётном числе.
while или for в JavaScript: что выбрать
Простое механическое правило:
- Перебор по счётчику в известном диапазоне →
for. Записьfor (let i = 0; i < arr.length; i++)держит инициализацию, условие и шаг в одной строке. - Проход по коллекции →
for...of. Чище, чем возиться с индексом вручную. - Крутим, пока не изменится состояние →
while. Обработка очереди, опрос, чтение потока, повторные попытки до успеха. - Нужно выполнить тело хотя бы один раз →
do...while.
По сути они взаимозаменяемы — любой for можно переписать через while и наоборот. Но если выбрать конструкцию, которая ложится на форму задачи, код будет сам себя документировать.
Бесконечный цикл в JavaScript: главное правило
У каждого цикла while должен быть чёткий ответ на вопрос: что его остановит?
Либо условие в заголовке рано или поздно станет ложным, либо внутри есть break, который гарантированно сработает. Если ни на то, ни на другое указать не получается — цикл ещё не готов.
// Плохо: условие никогда не меняется
let ready = false;
while (!ready) {
console.log("ожидание...");
// ничто здесь не меняет `ready`
}
// Хорошо: тело цикла влияет на условие
let ready = false;
let checks = 0;
while (!ready) {
checks++;
if (checks >= 3) ready = true;
}
В браузере бесконечный цикл намертво вешает вкладку. В Node — грузит ядро процессора на 100%, пока вы не убьёте процесс. Такие штуки лучше ловить до того, как код уйдёт в прод.
Что дальше: for...of и for...in
while хорош для сценария «крутимся, пока что-то не изменится». А вот когда нужно пройтись по массиву, строке или объекту элемент за элементом, в JavaScript есть две другие разновидности цикла, заточенные именно под это — for...of и for...in. О них поговорим дальше.
Часто задаваемые вопросы
Что такое цикл while в JavaScript?
Цикл while выполняет своё тело снова и снова, пока условие истинно. JavaScript сначала проверяет условие, потом выполняет блок кода, затем снова проверяет — и так по кругу. Если условие ложно уже при первой проверке, тело цикла не выполнится ни разу.
В чём разница между while и do...while?
while проверяет условие до выполнения тела — значит, цикл может не выполниться вообще. do...while сначала один раз выполняет тело, а уже потом проверяет условие, поэтому хотя бы одна итерация гарантирована. do...while удобен там, где первая итерация нужна всегда: например, когда мы запрашиваем ввод у пользователя.
Как выйти из цикла while в JavaScript?
Для немедленного выхода из цикла используется break, а для перехода к следующей итерации — continue. Именно break позволяет безопасно писать конструкции вида while (true): крутим бесконечный цикл, а внутри по нужному условию выходим через break.