Цикл заставляет интерпретатор JavaScript многократно выполнять один и тот же блок кода, называемый телом цикла. Каждое отдельное исполнение инструкций в теле цикла называется итерацией. В JavaScгipt доступны четыре инструкции циклов: while, do/while, for и for/in.
Цикл while
Инструкция while (англ. до тех пор, пока) создает цикл с предусловием. В скобках после слова while указывают некоторое логическое выражение или значение. Цикл начнется если значение этого выражения равно true
и будет работать до тех пор, пока это условие не обратится в false
. Общий синтаксис этого цикла выглядит так:
while (условие) {
инструкция
}
Следующий цикл while исполняется, пока значение переменной i меньше 3:
После окончания третьей итерации условие i < 3 больше не является истинным, поэтому цикл завершается.
Для создания бесконечного цикла в качестве условия достаточно задать булево значение true
:
while (true) {
инструкция
}
Это общепринятый способ создания бесконечного цикла. В прочих случаях (к примеру, если в рассмотренном нами примере убрать в коде i++) возможен вариант (в теории) создания бесконечного цикла. На практике, браузер выведет сообщение о «зависшем» скрипте и посетитель его остановит.
Цикл do...while
Инструкция do...while (англ. делай до тех пор, пока) отличается от цикла while тем, что в do...while сначала выполняется тело цикла, а затем проверяется условие продолжения цикла. Из-за такой особенности do...while называют циклом с постусловием. Таким образом, если условие do...while заведомо ложное, то хотя бы один раз блок операторов в теле цикла do...while всё равно выполнится.
Инструкция do...while представляет собой конструкцию из двух операторов, используемых совместно. Синтаксис этой конструкции следующий:
do {
// тело цикла
} while (условие);
Пример do...while:
Этот цикл продолжается, пока переменная i меньше 4. Она равна 0 в начале цикла и увеличивается на 1 на каждой итерации.
На заметку: Циклы с постусловием обычно используются, если тело цикла должно быть выполнено хотя бы один раз.
Цикл for
Инструкция for – это вариант цикла с предусловием, который состоит из трех необязательных выражений, заключенных в круглые скобки и разделенных точками с запятой, за которым следует оператор (обычно оператор блока), который должен выполняться в цикле. Она имеет следующий синтаксис:
for (инициализация; выражение; обновление) {
// ... тело цикла ...
}
Описание синтаксиса:
- Инициализация. Присваивается первоначальное значение переменной, обычно – счетчика. Выполняется только один раз в начале выполнения оператора. Областью действия этой переменной будет тело цикла.
- Выражение – булево выражение, которое вычисляется на каждой итерации цикла. Представляет собой условие продолжения работы оператора цикла. После того, как значение счетчика достигнет указанного предела, цикл завершится.
- Обновление – это значение, на которое будет увеличиваться или уменьшаться счетчик цикла. Вычисляется по завершении каждой итерации цикла. Чтобы оно было полезным, как и выражение инициализации, оно должно иметь побочные эффекты. В общем случае таким побочным эффектом служит операция присваивания, инкремента или декремента.
Пример цикла for:
Рассмотрим выполнение этого цикла более подробно:
- Инициализация: Переменная-счетчик, в данном случае х, инициализируется значением 1. Выполняется один-единственный раз, при заходе в цикл.
- Выражение: x < 4 – это условие продолжения цикла for, оно проверяется перед каждой итерацией и при входе в цикл на истинность. Если это так, то выполняются инструкции тела цикла (в данном случае – инструкция alert( x + " " );).
- Обновление: x++ – изменяет значение переменной-счетчика. Выполняется после тела на каждой итерации, но перед проверкой условия x < 4.
- Тело цикла: alert( x + " " ) – тело цикла обрамляется фигурными скобками, если тело цикла состоит из одной операции, то фигурные скобки можно опустить.
Иными словами, поток выполнения цикла: Инициализация → (если условие выражения true
→ тело цикла → обновление (x++)) → (если условие выражения true
→ тело цикла → обновление (x++)) → … и так далее, пока верно условие – x < 4.
Циклы for могут быть более сложными, чем в приведенных выше примерах. В некоторых циклах на каждой итерации может изменяться одновременно несколько переменных. В таких циклах часто применяется оператор «запятая» – он позволяет объединить несколько выражений инициализации и инкрементирования в одно, например:
Использование for без блоков
Все три выражения в заголовке цикла for являются необязательными.
Например, в блоке инициализации не требуется инициализировать переменные. Цикл в примере ниже полностью идентичен приведённому выше:
Как и блок инициализации, блок выражения также не является обязательным. Если вы опускаете выражение, то вы должны обязательно разбить цикл в теле, чтобы не создавать бесконечный цикл:
Можно опустить все три блока. Для избежания зацикливания используйте break для завершения цикла, а также изменяйте (увеличивайте или уменьшайте) переменную-счётчик, так чтобы условие для оператора break в какой-то момент сработало:
Примечание: Любое из выражений в цикле for может отсутствовать, однако сами точки с запятой обязательно должны присутствовать, иначе будет синтаксическая ошибка.
Цикл for...in
Цикл for...in используется для перебора всех свойств из объекта в случайном порядке и имеет следующий синтаксис:
for (variable in object) {
инструкция /* ... делать что-то с object[variable] ... */
}
В качестве nеременной (variable) можно подставить имя переменной или инструкцию var, объявляющую одну переменную. Переменной перед началом каждой итерации цикла присваивается в виде строки имя одного из свойств объекта. Как и в цикле for, оператор var здесь не обязателен, но его рекомендуется использовать, чтобы переменная была локальной. Справа от ключевого слова in указывается объект, свойства которого будут перебираться циклом. Если переменная, представляющая объект, будет иметь значение null
или undefined
цикл не выполнится ни разу. И как обычно, инструкция – это инструкция или блок инструкций, образующих тело цикла.
Пример итерации по свойствам объекта:
Как отмечалось ранее, если имя свойства хранится в переменной, то обратиться к нему можно только через квадратные скобки (myCar[prop]), а не через оператор «точка».
Свойства объектов в JavaScript не упорядочены, поэтому порядок возврата их имен в цикле for...in предсказать сложно. Все перечислимые свойства будут возвращены, но порядок их вывода может зависеть от браузера.
Согласно стандарта ECMAScript, если имя свойства – нечисловая строка, то такие свойства всегда перебираются в том же порядке, в каком присваивались. Так получилось в примере выше при выводе свойств объекта myCar. С другой стороны, если в качестве имени свойства выступает число или строка, которая может быть преобразована в числовой фомат, то браузеры осуществлят сортировку таких свойств в целях внутренней оптимизации. Вывод таких имен свойств объекта не будет соответствовать их оригинальному расположению.
Вложенные циклы
Цикл внутри другого цикла называется вложенным. Вложенность циклов формально не ограничивается, однако нужно быть предельно осторожным, чтобы не допустить зацикливания. При каждой итерации внешнего цикла вложенный цикл выполняется полностью. Вложенные циклы можно создавать с помощью инструкции for
и инструкции while
.
Пример вложенного цикла:
Теперь попытаемся разобраться, как это работает. Первый (внешний) цикл после каждой итерации увеличивает значение переменной i, а второй (внутренний) – переменной j. За одну итерацию внешнего цикла внутренний выполняется девять раз. По условию (i < 10) внешний цикл выполнится 9 раз. Соответственно вложенный цикл будет выполнятся тоже 9 раз, а код внутри него – 9*9 итого 81 раз.
Иными словами, код читаем так: натыкаемся на внешний цикл, делаем первый проход, во время прохода натыкаемся на еще один цикл (внутренний), делаем девять проходов по нему, каждый раз выводя текущее значение переменной j. Выводим значение i и далее возвращаемся в начало внешнего цикла для второго прохода и так 9 раз.
Операторы break и continue
Циклом можно управлять с помощью операторов break и continue.
Оператор break приводит к выходу из цикла или инструкции switch
и передает управление
операторам, следующим за ними.
В следующем примере создаётся счётчик, значения которого должны изменяться от 1
до 99
, однако оператор break прерывает цикл после 4
итераций:
Для вложенных циклов оператор break
используется с меткой, с помощью которой завершается работа «меченой» инструкции. Метка позволяет выйти из любого блока кода. Метка имеет вид "имя_метки:"
, имя должно быть уникальным. Она ставится перед циклом или блоком инструкций, которые нужно завершить с помощью break
:
Указание имени метки (без двоеточия) за ключевым словом break
приводит к выходу из цикла или инструкции. Между ключевым словом break
и именем метки не допускается перевод строки. Вызов break inner
завершит вложенный цикл, а break outer
ищет ближайший внешний цикл с такой меткой и переходит в его конец.
Оператор continue прерывает текущее выполнение цикла и переходит к выполнению следующего шага этого цикла. При этом, цикл while
возвращается непосредственно к своему условию, а цикл for
сначала вычисляет выражение инкремента, а затем возвращается к условию.
Рассмотрим пример:
В теле цикла инструкция if
с помощью оператора (%)
проверяет, является ли число четным. Если да, итерация цикла завершается до увеличения переменной num
, но цикл продолжается со следующей итерации со значением i
, увеличенным на единицу. Затем цикл выполняется до естественного завершения при значении i
, равном 10. Переменная num
подсчитывает количество итераций цикла. Окончательное значение num
равно 5, а не 9, потому что четные операции инкремента пропускаются из-за оператора continue
.
Оператор continue
, как и break
, можно использовать вместе с «помеченными» инструкциями для
возврата к конкретному месту в коде. Чаще всего это делается во вложенных циклах, например:
В этом примере для внешнего цикла for
добавлена метка outer_mask. Каждый цикл включает 5 итераций, то есть инструкция num++
предположительно должна быть выполнена 25 раз, после чего переменная num
должна быть равна 25. Оператор continue
завершает выполнение внутреннего цикла, начиная новую итерацию внешнего. Она выполняется, когда j
равно 3, то есть пропускаются две итерации внутреннего цикла, из-за чего num
в итоге имеет значение 23.
Задачи
-
Число «задом наперед»
Пользователь вводит целое число. Напишите код, который выведет число, обратное по порядку составляющих его цифр введенному. Например, введено 9876, надо вывести 6789. Решите задачу через цикл while.
Показать решениеРешение:
- Найдем остаток от деления на 10 исходного числа
num1
. Получим его последнюю цифруdigit
. - Добавим эту цифру к новому числу
num2
. - Разделим нацело на 10 исходное число
num1
и округлим до целых. Тем самым избавимся от последней цифры в нем. Полученное число сохраним вnum1
. - Снова найдем остаток от деления на 10 того, что осталось от первого числа
num1
. Запомним эту цифру. - Умножим на 10 второе число. Тем самым увеличим его разрядность до двух и сдвинем первую цифру в разряд десятков.
- Добавим к полученному второму числу запомненную ранее цифру
digit
из первого числа. - Будем повторять перечисленные действия пока исходное число не уменьшится до нуля, т.е. пока не избавимся от всех его разрядов.
-
Сумма свойств объекта
Есть объект
users
в которм перечислен возраст участников. Напишите код, который выведет суммарный возраст всех участников. Решите задачу через цикл for...in.var users = { "John": 28, "Mark": 30, "David": 25, "Richard": 42 }; /* ...ваш код... */
Решение:
-
Найти сумму четных цифр числа
Пользователь вводит натуральное число. Найти сумму четных цифр, входящих в его состав.
Показать решениеРешение:
- В переменную sum будем суммировать все четные числа.
- Пока значение введенного числа (n) больше нуля выполнять пункты 3 – 5.
- Извлекать последнюю цифру числа (n) (путем нахождения остатка от деления на 10) и проверять ее на четность (путем нахождения остатка от деления на 2).
- Если цифра четная, то добавлять ее к sum.
- Избавиться от последней цифры числа путем ее деления нацело на 10.
- Вывести значение sum в консоль. Перейдите во вкладку Console инструментов разработчика ( Ctrl+Shift+J / Cmd+Shift+J ).
-
Повторять цикл, пока пользователь не введёт 0
Напишите цикл, который предлагает
prompt
ввести число. Если посетитель ввёл число – попросить ввести ещё раз, и так далее.
Цикл должен спрашивать ввести число пока либо посетитель не введёт0
, либо не нажмёт кнопкуCancel (ESC)
. После ввода нуля, показать на экран количество чисел, которые были введены, их общую сумму и среднее арифметическое.Показать решениеРешение:
-
Сумма нечётных чисел в диапазоне
Необходимо суммировать все нечётные целые числа в диапазоне, который введёт пользователь с клавиатуры.
Показать решениеРешение:
-
Равнобедренный треугольник из символов
Нарисовать равнобедренный треугольник из символов
*
. Высоту выбирает пользователь. Например, при высоте = 6, на экране треугольник должен выглядеть так:Показать решениеРешение:
-
Найти наибольшую цифру натурального числа
Пользователь вводит с клавиатуры натуральное число. Найдите его наибольшую цифру и выведите её через
alert
.
Например, введено число 987560. Наибольшая цифра в нем 9.Показать решениеРешение:
- Переменная n – заданное число, а переменная m – максимальная цифра в этом числе.
- Допустим, что последняя цифра числа и есть максимальная. Извлечем ее используя оператор нахождения остатка при делении на 10. Присвоим значение переменной m.
- Избавимся от последней цифры с помощью операции деления на 10 и округления при помощи побитового оператора.
- Далее в цикле будем извлекать с конца числа поочерёдно каждую его цифру и сравнивать со значением m. Если очередная цифра будет больше, чем максимальное значение, то будем присваивать ее переменной m.
- Также в цикле будем каждый раз избавляться от последней, уже учтенной, цифры. Цикл завершит свою работу, когда переменная n станет равной нулю, т. е. после того, когда будут перебраны все цифры числа.
- В конце кода через
alert
выведем значение m на экран. Это и будет наибольшая цифра введенного числа.
-
-
-
-
- Найдем остаток от деления на 10 исходного числа
Комментарии
<code>
, несколько строчек кода — в теги<pre><code>
...ваш код...</code></pre>
.