При написании скриптов зачастую встает задача сделать однотипное действие много раз.
Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
Для многократного повторения одного участка кода – предусмотрены циклы.
Цикл while имеет вид:
Пока условие верно – выполняется код из тела цикла.
Например, цикл ниже выводит i пока i < 3:
Повторение цикла по-научному называется «итерация». Цикл в примере выше совершает три итерации.
Если бы i++ в коде выше не было, то цикл выполнялся бы (в теории) вечно. На практике, браузер выведет сообщение о «зависшем» скрипте и посетитель его остановит.
Бесконечный цикл можно сделать и проще:
Условие в скобках интерпретируется как логическое значение, поэтому вместо while (i!=0) обычно пишут while (i):
Проверку условия можно поставить под телом цикла, используя специальный синтаксис do..while:
Цикл, описанный, таким образом, сначала выполняет тело, а затем проверяет условие.
Например:
Синтаксис do..while редко используется, т.к. обычный while нагляднее – в нём не приходится искать глазами условие и ломать голову, почему оно проверяется именно в конце.
Чаще всего применяется цикл for. Выглядит он так:
Пример цикла, который выполняет alert(i) для i от 0 до 2 включительно (до 3):
Здесь:
i=0.i<3.i++.alert(i), т.е. код внутри фигурных скобок (они не обязательны, если только одна операция)Цикл выполняется так:
i=0 выполняется один-единственный раз, при заходе в цикл.i<3 проверяется перед каждой итерацией и при входе в цикл, если оно нарушено, то происходит выход.alert(i).i++ выполняется после тела на каждой итерации, но перед проверкой условия.Иными словами, поток выполнения: начало → (если условие → тело → шаг) → (если условие → тело → шаг) → … и так далее, пока верно условие.
В цикле также можно определить переменную:
Эта переменная будет видна и за границами цикла, в частности, после окончания цикла i станет равно 3.
Любая часть for может быть пропущена.
Например, можно убрать начало. Цикл в примере ниже полностью идентичен приведённому выше:
Можно убрать и шаг:
А можно и вообще убрать всё, получив бесконечный цикл:
При этом сами точки с запятой ; обязательно должны присутствовать, иначе будет ошибка синтаксиса.
for..inСуществует также специальная конструкция for..in для перебора свойств объекта.
Мы познакомимся с ней позже, когда будем говорить об объектах.
Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива break.
Например, следующий код подсчитывает сумму вводимых чисел до тех пор, пока посетитель их вводит, а затем – выдаёт:
Директива break в строке (*), если посетитель ничего не ввёл, полностью прекращает выполнение цикла и передаёт управление на строку за его телом, то есть на alert.
Вообще, сочетание «бесконечный цикл + break» – отличная штука для тех ситуаций, когда условие, по которому нужно прерваться, находится не в начале-конце цикла, а посередине.
Директива continue прекращает выполнение текущей итерации цикла.
Она – в некотором роде «младшая сестра» директивы break: прерывает не весь цикл, а только текущее выполнение его тела, как будто оно закончилось.
Её используют, если понятно, что на текущем повторе цикла делать больше нечего.
Например, цикл ниже использует continue, чтобы не выводить чётные значения:
Для чётных i срабатывает continue, выполнение тела прекращается и управление передаётся на следующий проход for.
continue позволяет обойтись без скобокЦикл, который обрабатывает только нечётные значения, мог бы выглядеть так:
С технической точки зрения он полностью идентичен. Действительно, вместо continue можно просто завернуть действия в блок if. Однако, мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри if более длинный, то это ухудшает читаемость, в отличие от варианта с continue.
Обычно мы можем заменить if на оператор вопросительный знак '?'.
То есть, запись:
…Аналогична записи:
В обоих случаях в зависимости от условия выполняется либо a() либо b().
Но разница состоит в том, что оператор вопросительный знак '?', использованный во второй записи, возвращает значение.
Синтаксические конструкции, которые не возвращают значений, нельзя использовать в операторе '?'.
К таким относятся большинство конструкций и, в частности, break/continue.
Поэтому такой код приведёт к ошибке:
Впрочем, как уже говорилось ранее, оператор вопросительный знак '?' не стоит использовать таким образом. Это – всего лишь ещё одна причина, почему для проверки условия предпочтителен if.
Бывает нужно выйти одновременно из нескольких уровней цикла.
Например, внутри цикла по i находится цикл по j, и при выполнении некоторого условия мы бы хотели выйти из обоих циклов сразу:
В коде выше для этого использована метка.
Метка имеет вид "имя:", имя должно быть уникальным. Она ставится перед циклом, вот так:
Можно также выносить её на отдельную строку:
Вызов break outer ищет ближайший внешний цикл с такой меткой и переходит в его конец.
В примере выше это означает, что будет разорван самый внешний цикл и управление перейдёт на alert.
Директива continue также может быть использована с меткой, в этом случае управление перепрыгнет на следующую итерацию цикла с меткой.
JavaScript поддерживает три вида циклов:
while – проверка условия перед каждым выполнением.do..while – проверка условия после каждого выполнения.for – проверка условия перед каждым выполнением, а также дополнительные настройки.Чтобы организовать бесконечный цикл, используют конструкцию while(true). При этом он, как и любой другой цикл, может быть прерван директивой break.
Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву continue.
Обе этих директивы поддерживают «метки», которые ставятся перед циклом. Метки – единственный способ для break/continue повлиять на выполнение внешнего цикла.
Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.