Циклы while, for

При написании скриптов зачастую встает задача сделать однотипное действие много раз.

Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.

Для многократного повторения одного участка кода – предусмотрены циклы.

Цикл while

Цикл while имеет вид:

Цикл while

Пока условие верно – выполняется код из тела цикла.

Например, цикл ниже выводит i пока i < 3:

Цикл while

Повторение цикла по-научному называется «итерация». Цикл в примере выше совершает три итерации.

Если бы i++ в коде выше не было, то цикл выполнялся бы (в теории) вечно. На практике, браузер выведет сообщение о «зависшем» скрипте и посетитель его остановит.

Бесконечный цикл можно сделать и проще:

Цикл while

Условие в скобках интерпретируется как логическое значение, поэтому вместо while (i!=0) обычно пишут while (i):

Цикл while

Цикл do…while

Проверку условия можно поставить под телом цикла, используя специальный синтаксис do..while:

Цикл do…while

Цикл, описанный, таким образом, сначала выполняет тело, а затем проверяет условие.

Например:

Цикл do…while

Синтаксис do..while редко используется, т.к. обычный while нагляднее – в нём не приходится искать глазами условие и ломать голову, почему оно проверяется именно в конце.

Цикл for

Чаще всего применяется цикл for. Выглядит он так:

Цикл for

Пример цикла, который выполняет alert(i) для i от 0 до 2 включительно (до 3):

Цикл for

Здесь:

  • Начало: i=0.
  • Условие: i<3.
  • Шаг: i++.
  • Тело: alert(i), т.е. код внутри фигурных скобок (они не обязательны, если только одна операция)

Цикл выполняется так:

  1. Начало: i=0 выполняется один-единственный раз, при заходе в цикл.
  2. Условие: i<3 проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.
  3. Тело: alert(i).
  4. Шаг: i++ выполняется после тела на каждой итерации, но перед проверкой условия.
  5. Идти на шаг 2.

Иными словами, поток выполнения: начало → (если условиетелошаг) → (если условиетелошаг) → … и так далее, пока верно условие.

На заметку:

В цикле также можно определить переменную:

Цикл for

Эта переменная будет видна и за границами цикла, в частности, после окончания цикла i станет равно 3.

Пропуск частей for

Любая часть for может быть пропущена.

Например, можно убрать начало. Цикл в примере ниже полностью идентичен приведённому выше:

Пропуск частей for

Можно убрать и шаг:

Пропуск частей for

А можно и вообще убрать всё, получив бесконечный цикл:

Пропуск частей for

При этом сами точки с запятой ; обязательно должны присутствовать, иначе будет ошибка синтаксиса.

for..in

Существует также специальная конструкция for..in для перебора свойств объекта.

Мы познакомимся с ней позже, когда будем говорить об объектах.

Прерывание цикла: break

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

Например, следующий код подсчитывает сумму вводимых чисел до тех пор, пока посетитель их вводит, а затем – выдаёт:

Прерывание цикла: break

Директива break в строке (*), если посетитель ничего не ввёл, полностью прекращает выполнение цикла и передаёт управление на строку за его телом, то есть на alert.

Вообще, сочетание «бесконечный цикл + break» – отличная штука для тех ситуаций, когда условие, по которому нужно прерваться, находится не в начале-конце цикла, а посередине.

Следующая итерация: continue

Директива continue прекращает выполнение текущей итерации цикла.

Она – в некотором роде «младшая сестра» директивы break: прерывает не весь цикл, а только текущее выполнение его тела, как будто оно закончилось.

Её используют, если понятно, что на текущем повторе цикла делать больше нечего.

Например, цикл ниже использует continue, чтобы не выводить чётные значения:

Прерывание цикла: break

Для чётных i срабатывает continue, выполнение тела прекращается и управление передаётся на следующий проход for.

Директива continue позволяет обойтись без скобок

Цикл, который обрабатывает только нечётные значения, мог бы выглядеть так:

Директива continue

С технической точки зрения он полностью идентичен. Действительно, вместо continue можно просто завернуть действия в блок if. Однако, мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри if более длинный, то это ухудшает читаемость, в отличие от варианта с continue.

Нельзя использовать break/continue справа от оператора „?“

Обычно мы можем заменить if на оператор вопросительный знак '?'.

То есть, запись:

Директива continue

…Аналогична записи:

Директива continue

В обоих случаях в зависимости от условия выполняется либо a() либо b().

Но разница состоит в том, что оператор вопросительный знак '?', использованный во второй записи, возвращает значение.

Синтаксические конструкции, которые не возвращают значений, нельзя использовать в операторе '?'.

К таким относятся большинство конструкций и, в частности, break/continue.

Поэтому такой код приведёт к ошибке:

break / continue

Впрочем, как уже говорилось ранее, оператор вопросительный знак '?' не стоит использовать таким образом. Это – всего лишь ещё одна причина, почему для проверки условия предпочтителен if.

Метки для break/continue

Бывает нужно выйти одновременно из нескольких уровней цикла.

Например, внутри цикла по i находится цикл по j, и при выполнении некоторого условия мы бы хотели выйти из обоих циклов сразу:

Метки для break/continue

В коде выше для этого использована метка.

Метка имеет вид "имя:", имя должно быть уникальным. Она ставится перед циклом, вот так:

Метки для break/continue

Можно также выносить её на отдельную строку:

Метки для break/continue

Вызов break outer ищет ближайший внешний цикл с такой меткой и переходит в его конец.

В примере выше это означает, что будет разорван самый внешний цикл и управление перейдёт на alert.

Директива continue также может быть использована с меткой, в этом случае управление перепрыгнет на следующую итерацию цикла с меткой.

Итого

JavaScript поддерживает три вида циклов:

  • while – проверка условия перед каждым выполнением.
  • do..while – проверка условия после каждого выполнения.
  • for – проверка условия перед каждым выполнением, а также дополнительные настройки.

Чтобы организовать бесконечный цикл, используют конструкцию while(true). При этом он, как и любой другой цикл, может быть прерван директивой break.

Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву continue.

Обе этих директивы поддерживают «метки», которые ставятся перед циклом. Метки – единственный способ для break/continue повлиять на выполнение внешнего цикла.

Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.