- Цикл for
- Синтаксис for
- Пример №1
- Пример №2
- Необязательные элементы в цикле for
- Пример №3
- Пример №4
- Пример №5
- Прерывание цикла — break
- Пример №6
- Пример №7
- Завершение текущей итерации — continue
- Пример №8
- Метки для continue и break
- Пример №9
- Пример №10
- Итого
- Циклы while и for
- Цикл «while»
- Цикл «do…while»
- Цикл «for»
- Пропуск частей «for»
- Прерывание цикла: «break»
- Переход к следующей итерации: continue
- Метки для break/continue
- Итого
Цикл for
For — это оператор в JavaScript для создания цикла, который состоит из трёх необязательных условий. Цикл for считается более сложным чем while , но тем не менее более распространен.
Синтаксис for
for (начальное выражение; условие; шаг) < // инструкция (тело цикла) >
Начальное выражение — условие выполняется один раз при входе в цикл и обычно используется для инициализации счетчика.
Условие — проверяется при каждой итерации. Если условие true происходит запуск цикла, при false остановка.
Тело цикла — код из тела цикла выполняется при каждой итерации до тех пор пока условие true .
Шаг — выражение выполняется после исполнения кода из тела цикла при каждой итерации перед проверкой условия.
Пример №1
let n = 0 — выполняется один раз при входе в цикл, переменной n задается значение 0.
n — далее проверяется условие, где n должно быть меньше 5, если это true , тогда поток выполнения кода идет дальше.
console.log(n) — после каждой итерации в console выводится значение переменной n , на первом этапе это 0.
n++ — после выполнения тела цикла n увеличивается на единицу.
Далее процесс происходит заново, до тех пор пока n не станет равна 5, тогда цикл завершится. Результатом скрипта является вывод в console цифр 0, 1, 2, 3, 4.
Пример №2
В первом выражении цикла for можно объявить несколько переменных, в этом примере это i и n , но их может быть и больше. В третьем выражении ситуация сходная с каждым шагом i и n увеличиваются на единицу, при необходимости можно добавить операции и над другими переменными.
Необязательные элементы в цикле for
Все три выражения в цикле for расположенные в круглых скобках необязательны и могут быть пропущены.
Пример №3
Такой код отработает идентично, тому, где переменная n была бы объявлена в первом выражении for , а не перед циклом.
Пример №4
В этом случае шаг был перенесен в тело цикла.
Пример №5
Здесь отсутствуют все три выражения и это тоже не ошибка, правда это делает цикл бесконечным. В таком случае можно предусмотреть окончание цикла с помощью директивы break.
Прерывание цикла — break
Директива break позволяет прервать цикл for в любой момент
Пример №6
При каждой итерации в теле цикла происходит проверка if (n > 10) и когда n станет больше 10, цикл прервется.
Пример №7
Здесь более наглядно можно увидеть принцип работы break . Как только n достигнет пяти, цикл прервется и в модальном окне появится результат. В свою очередь условие n будет проигнорировано.
Завершение текущей итерации — continue
Директива continue применяется в том случае, если необходимо прервать не весь цикл, а одну или более итераций.
Пример №8
Данный скрипт будет выводить по порядку в модальном окне только нечетные числа, когда попадается четное число, срабатывает continue , который завершает данную итерацию.
Метки для continue и break
При вложенности циклов директивы continue и break , могут не помочь решить нужную задачу, в этом случае на помощь приходят метки. Допустим необходимо при определенных условиях выйти из всех уровней цикла.
Пример №9
let n, i; cancelLoops: for (n = 0; n < 4; n++) < for (i = 0; i < 4; i++) < if (n === 3 && i === 3) < break cancelLoops; >console.log('n = ' + n + ', i = ' + i); > >
Метка cancelLoops обозначает верхний цикл и при достижении условия (n === 3 && i === 3) команда break cancelLoops его прерывает
Пример №10
passLoop: for (n = 0; n < 4; n++) < for (i = 0; i < 4; i++) < if (n === 2 && i === 2) < continue passLoop; >console.log('n = ' + n + ', i = ' + i); > >
При достижении условия (n === 2 && i === 2) команда continue passLoop завершает текущую итерацию и переносит поток выполнения кода в начало верхнего цикла.
Итого
Цикл for состоит из трех необязательных выражений и тела цикла. Для того, чтобы прервать исполнение for используется команда break , для окончания итерации continue . При работе с вложенными циклами можно решать задачи с помощью меток, которые работают, как с continue , так и с break .
Skypro — научим с нуля
Циклы while и for
При написании скриптов зачастую встаёт задача сделать однотипное действие много раз.
Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
Для многократного повторения одного участка кода предусмотрены циклы.
Небольшое объявление для продвинутых читателей.
В этой статье рассматриваются только базовые циклы: while , do..while и for(..;..;..) .
Если вы пришли к этой статье в поисках других типов циклов, вот указатели:
- См. for…in для перебора свойств объекта.
- См. for…of и Перебираемые объекты для перебора массивов и перебираемых объектов.
В противном случае, продолжайте читать.
Цикл «while»
Цикл while имеет следующий синтаксис:
Код из тела цикла выполняется, пока условие condition истинно.
Например, цикл ниже выводит i , пока i < 3 :
Одно выполнение тела цикла по-научному называется итерация. Цикл в примере выше совершает три итерации.
Если бы строка i++ отсутствовала в примере выше, то цикл бы повторялся (в теории) вечно. На практике, конечно, браузер не позволит такому случиться, он предоставит пользователю возможность остановить «подвисший» скрипт, а JavaScript на стороне сервера придётся «убить» процесс.
Любое выражение или переменная может быть условием цикла, а не только сравнение: условие while вычисляется и преобразуется в логическое значение.
Например, while (i) – более краткий вариант while (i != 0) :
Если тело цикла состоит лишь из одной инструкции, мы можем опустить фигурные скобки :
Цикл «do…while»
Проверку условия можно разместить под телом цикла, используя специальный синтаксис do..while :
Цикл сначала выполнит тело, а затем проверит условие condition , и пока его значение равно true , он будет выполняться снова и снова.
Такая форма синтаксиса оправдана, если вы хотите, чтобы тело цикла выполнилось хотя бы один раз, даже если условие окажется ложным. На практике чаще используется форма с предусловием: while(…) .
Цикл «for»
Более сложный, но при этом самый распространённый цикл — цикл for .
Давайте разберёмся, что означает каждая часть, на примере. Цикл ниже выполняет alert(i) для i от 0 до (но не включая) 3 :
Рассмотрим конструкцию for подробней:
часть | ||
---|---|---|
начало | let i = 0 | Выполняется один раз при входе в цикл |
условие | i < 3 | Проверяется перед каждой итерацией цикла. Если оно вычислится в false , цикл остановится. |
тело | alert(i) | Выполняется снова и снова, пока условие вычисляется в true . |
шаг | i++ | Выполняется после тела цикла на каждой итерации перед проверкой условия. |
В целом, алгоритм работы цикла выглядит следующим образом:
Выполнить начало → (Если условие == true → Выполнить тело, Выполнить шаг) → (Если условие == true → Выполнить тело, Выполнить шаг) → (Если условие == true → Выполнить тело, Выполнить шаг) → .
То есть, начало выполняется один раз, а затем каждая итерация заключается в проверке условия , после которой выполняется тело и шаг .
Если тема циклов для вас нова, может быть полезным вернуться к примеру выше и воспроизвести его работу на листе бумаги, шаг за шагом.
Вот в точности то, что происходит в нашем случае:
// for (let i = 0; i < 3; i++) alert(i) // Выполнить начало let i = 0; // Если условие == true → Выполнить тело, Выполнить шаг if (i < 3) < alert(i); i++ >// Если условие == true → Выполнить тело, Выполнить шаг if (i < 3) < alert(i); i++ >// Если условие == true → Выполнить тело, Выполнить шаг if (i < 3) < alert(i); i++ >// . конец, потому что теперь i == 3
В примере переменная счётчика i была объявлена прямо в цикле. Это так называемое «встроенное» объявление переменной. Такие переменные существуют только внутри цикла.
for (let i = 0; i < 3; i++) < alert(i); // 0, 1, 2 >alert(i); // ошибка, нет такой переменной
Вместо объявления новой переменной мы можем использовать уже существующую:
let i = 0; for (i = 0; i < 3; i++) < // используем существующую переменную alert(i); // 0, 1, 2 >alert(i); // 3, переменная доступна, т.к. была объявлена снаружи цикла
Пропуск частей «for»
Любая часть for может быть пропущена.
Для примера, мы можем пропустить начало если нам ничего не нужно делать перед стартом цикла.
let i = 0; // мы уже имеем объявленную i с присвоенным значением for (; i < 3; i++) < // нет необходимости в "начале" alert( i ); // 0, 1, 2 >
Это сделает цикл аналогичным while (i < 3) .
А можно и вообще убрать всё, получив бесконечный цикл:
При этом сами точки с запятой ; обязательно должны присутствовать, иначе будет ошибка синтаксиса.
Прерывание цикла: «break»
Обычно цикл завершается при вычислении условия в false .
Но мы можем выйти из цикла в любой момент с помощью специальной директивы break .
Например, следующий код подсчитывает сумму вводимых чисел до тех пор, пока посетитель их вводит, а затем – выдаёт:
let sum = 0; while (true) < let value = +prompt("Введите число", ''); if (!value) break; // (*) sum += value; >alert( 'Сумма: ' + sum );
Директива break в строке (*) полностью прекращает выполнение цикла и передаёт управление на строку за его телом, то есть на alert .
Вообще, сочетание «бесконечный цикл + break » – отличная штука для тех ситуаций, когда условие, по которому нужно прерваться, находится не в начале или конце цикла, а посередине или даже в нескольких местах его тела.
Переход к следующей итерации: continue
Директива continue – «облегчённая версия» break . При её выполнении цикл не прерывается, а переходит к следующей итерации (если условие все ещё равно true ).
Её используют, если понятно, что на текущем повторе цикла делать больше нечего.
Например, цикл ниже использует continue , чтобы выводить только нечётные значения:
Для чётных значений i , директива continue прекращает выполнение тела цикла и передаёт управление на следующую итерацию for (со следующим числом). Таким образом alert вызывается только для нечётных значений.
Цикл, который обрабатывает только нечётные значения, мог бы выглядеть так:
С технической точки зрения он полностью идентичен. Действительно, вместо continue можно просто завернуть действия в блок if .
Однако мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри if более длинный, то это ухудшает читаемость, в отличие от варианта с continue .
Обратите внимание, что эти синтаксические конструкции не являются выражениями и не могут быть использованы с тернарным оператором ? . В частности, использование таких директив, как break/continue , вызовет ошибку.
Например, если мы возьмём этот код:
…и перепишем его, используя вопросительный знак:
(i > 5) ? alert(i) : continue; // continue здесь приведёт к ошибке
…то будет синтаксическая ошибка.
Это ещё один повод не использовать оператор вопросительного знака ? вместо if .
Метки для break/continue
Бывает, нужно выйти одновременно из нескольких уровней цикла сразу.
Например, в коде ниже мы проходимся циклами по i и j , запрашивая с помощью prompt координаты (i, j) с (0,0) до (2,2) :
for (let i = 0; i < 3; i++) < for (let j = 0; j < 3; j++) < let input = prompt(`Значение на координатах ($,$)`, ''); // Что если мы захотим перейти к Готово (ниже) прямо отсюда? > > alert('Готово!');
Нам нужен способ остановить выполнение, если пользователь отменит ввод.
Обычный break после input лишь прервёт внутренний цикл, но этого недостаточно. Достичь желаемого поведения можно с помощью меток.
Метка имеет вид идентификатора с двоеточием перед циклом:
Вызов break в цикле ниже ищет ближайший внешний цикл с такой меткой и переходит в его конец.
outer: for (let i = 0; i < 3; i++) < for (let j = 0; j < 3; j++) < let input = prompt(`Значение на координатах ($,$)`, ''); // если пустая строка или Отмена, то выйти из обоих циклов if (!input) break outer; // (*) // сделать что-нибудь со значениями. > > alert('Готово!');
В примере выше это означает, что вызовом break outer будет разорван внешний цикл до метки с именем outer .
Таким образом управление перейдёт со строки, помеченной (*) , к alert(‘Готово!’) .
Можно размещать метку на отдельной строке:
Директива continue также может быть использована с меткой. В этом случае управление перейдёт на следующую итерацию цикла с меткой.
Метки не дают возможности передавать управление в произвольное место кода.
Например, нет возможности сделать следующее:
break label; // не прыгает к метке ниже label: for (. )
Директива break должна находиться внутри блока кода. Технически, подойдет любой маркированный блок кода, например:
…Хотя в 99.9% случаев break используется внутри циклов, как мы видели в примерах выше.
К слову, continue возможно только внутри цикла.
Итого
Мы рассмотрели 3 вида циклов:
- while – Проверяет условие перед каждой итерацией.
- do..while – Проверяет условие после каждой итерации.
- for (;;) – Проверяет условие перед каждой итерацией, есть возможность задать дополнительные настройки.
Чтобы организовать бесконечный цикл, используют конструкцию while (true) . При этом он, как и любой другой цикл, может быть прерван директивой break .
Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву continue .
Обе этих директивы поддерживают метки, которые ставятся перед циклом. Метки – единственный способ для break/continue выйти за пределы текущего цикла, повлиять на выполнение внешнего.
Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.