Как подсчитать количество итераций цикла за 1 секунду?
Приветствую, появилась довольно тривиальная задача, но уже полчаса ломаю голову над ее решением.
Мне нужно подсчитать сколько раз проходит цикл за 1 секунду, проще говоря количество итераций в секунду, как это можно реализовать?
- Вопрос задан более трёх лет назад
- 1157 просмотров
Комментировать
Решения вопроса 1
Stopwatch stopWatch = new Stopwatch(); stopWatch.Start(); int iterationCounter = 0; while(true)< //todo iterationCounter++; if(stopWatch.ElapsedMilliseconds >= 1000) < Console.WriteLine("iterations "+iterationCounter); break; >> stopWatch.Stop();
P.S. Ну это не идеально за 1 секунду, так как одна секунда может истечь в момент обработки вашего кода, тогда если не нужно считать такую итерацию, от счетчика отнимите 1 если ElapsedMilliseconds > 1000
Ответ написан более трёх лет назад
Griboks @Griboks Куратор тега C#
Лучше продлить время замера до нескольких минут, а потом разделить на время.
Ответы на вопрос 2
Самый лучший программист
var sw = new Stopwatch(); sw.Start(); sw.Stop(); mssec = sw.ElapsedMilliseconds;
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
QA automation
Запустите цикл на 1000 раз(для примера), замерьте время(N).
Время переведите в секунды(если замеряли в милисекундах) и 1000\N = колличество итераций за секунду.
Ответ написан более трёх лет назад
RoxxelRoxx @RoxxelRoxx Автор вопроса
А если количество итераций цикла не постоянное? Т.е первый раз прошло 20 раз в секунду, а во второй уже 10, при том что цикл бесконечный
А это уже другой вопрос, тогда вам необходимо проверять алгоритм на одинаковых данных, либо бо же вычислять среднее арифметическое.
Если вы имели ввиду — вывод колличества итераций на каждую секунду, вам надо запускать таймер и каждую секунду обнулять счетчик, добавляя результаты например в лист, а потом уже, его читать.
Итерация
Итерация (от лат. iteratio) – это единичное повторение того или иного действия. Этот термин является важной составляющей программирования и применяется относительно циклов, исполняющихся в процессе работы программы несколько раз. Суть: цикл выполнился единожды, значит, прошла одна итерация. Также существуют другие варианты этого определения в зависимости от контекста. Например, при организации разработки ПО по методике Agile «итерация» – это отрезок рабочего процесса длиной в 2-3 недели (в Scrum то же самое понятие называют «спринт»).
Пример, как функционирует итерация
В зависимости от своей задачи циклы могут работать по-разному. В некоторых случаях они проходят заранее заданное количество итераций и останавливаются. В других – остановка происходит по достижении определенного результата (например, верно/неверно). Число итераций тоже зависит от конкретной программы, их может быть как бесконечное количество, так и ноль.
Приведем пример, сколько итераций потребуется программе, чтобы выполнить простую функцию.
Представьте случайное число X, которое нужно умножить на 15, чтобы добиться результата, равного 200 или больше (это точка, после которой циклы перестанут повторяться). Программа будет проверять соответствие условию, умножать, снова проверять соответствие и повторять эти действия, пока не добьется заданного результата. Количество итераций напрямую зависит от того, какое значение было у X. Если это было 8, то программе потребуется 2 цикла, чтобы получить 240, что соответствует условию. При этом, если X будет равен 201, то цикл не выполнится, потому что результат уже достигнут без умножений.
Как используются итерации в программировании
Процесс разработки часто требует решения задач, в которых для достижения цели необходимо повторить одно и то же действие несколько раз. Это могут быть разные вещи: получение информации, вывод сообщения, отправка оповещения и пр. В программировании работает важный принцип DRY, который расшифровывается так don’t repeat yourself – «не повторяйся». В соответствии с этим «законом» не стоит вручную выполнять все описанные выше действия. Поэтому их лучше делегировать написанному разработчиком циклу, который сделает необходимое число итераций вплоть до достижения результата.
С помощью итераций можно контролировать то, как программа будет выполнять поставленную перед ней задачу. На основе этого выделяют два вида повторений.
- Контролируемые подсчетом. Разработчик может заставить цикл исполниться, например, 10 раз подряд – именно это будет условием, чтобы перестали запускаться последовательные итерации. Как правило, такие итерации применяют для ввода операторов for. В этом случае разработчик обозначает стартовую точку итерации и задает число повторений.
- Условные. Разработчик может установить условием выполнения не количество повторений, а некий конкретный итог. Как в примере выше, это может быть достижение определенного числа или получение информации от конкретного источника. Программа будет проверять исполнение условия в начале или по окончании каждой итерации (зависит от того, как задаст программист). Если результат будет достигнут, цикл прекратится. При этом специалисту не придется делать что-либо вручную. Такой подход практикуется при машинном обучении.
Итерации встречаются практически во всех распространенных языках программирования. Ими пользуются программисты на C++, PHP, JavaScript, Python и многих других.
Специфика создания и работы итераций
Разработчик создает сложные и простые итерации, чтобы добиться определенной цели. Для этого он выполняет следующие действия и проверяет работу получившегося кода.
Объявление цикла. Программист описывает условия для выполнения цикла перед тем, как объявить его, то есть указывает, в каком случае работа будет считаться выполненной. Это может быть число итераций или другие события. Этот процесс – объявление цикла с предусловием.
Цикл с предусловием выглядит примерно так:
В некоторых случаях исполнение программы сразу запускает цикл и сверяется со своей целью только после завершения итерации – это цикл с постусловием.
Схема цикла с постусловием:
Написание тела цикла. После объявления программист должен написать тело – то, что непосредственно будет делать цикл, какие именно итерации будут выполняться. Это подпрограмма, поэтому для ее отделения от основного кода используются <> или слова begin и end. Если программист использует Python, то для этих целей он применяет отступы.
Работа итераций. В своей работе программа может дойти до момента, когда нужно выполнить цикл и все его итерации. Сначала она считывает строку с объявлением. Затем проверяются условия выхода из цикла, если их нет, запускается тело. Каждая итерация предполагает единоразовое исполнение цикла. Программа будет сверяться с нужным результатом и повторять действия из тела цикла столько раз, сколько потребуется.
Разные варианты входа в цикл. Существуют разные варианты того, как будет работать подпрограмма в рамках основного кода. Условия могут проверяться до входа в тело, еще на этапе объявления цикла. Тогда ничего не запускается. В противном случае программа сразу входит в тело цикла и проверяет, соответствует ли выполнение кода условию, только после первой итерации. Получается, если результат соответствует условиям, цикл выполнится либо 0 раз, либо 1 раз.
Что означает «итерируемый объект»
Итерируемые объекты – те, чье содержимое поддается пересчету. Наиболее примитивный пример итерируемого объекта – строка, потому что в рамках цикла ее возможно пройти от начала до конца побуквенно (количество символов в ней измеримо, и у каждого из них есть строго заданное место).
Чуть более сложный пример подобных объектов – массив. Он представляет собой переменную, внутри которой перечислены значения, имеющие порядковый номер. Поскольку структура массива сходна с числовым рядом, ее тоже можно пересчитать. Для этого можно двигаться в направлении от первого объекта к последнему и наоборот.
Итерируемые объекты тесно связаны с понятием итерируемости, которое встречается во многих современных языках программирования (например, JavaScript). Необходимость обрабатывать подобные объекты часто возникает при парсинге, анализе строк или прочих данных. Понятие итерируемости важно с точки зрения того, можно ли обработать объект, изучить его содержимое.
Итерация и итератор – не перепутайте
Итератор – это похожее по звучанию понятие, которое представляет собой переменную-счетчик. Она предназначена для записи количества итераций цикла. Как правило, итераторы прописывают для циклов, которые должны выполняться определенное количество раз.
Принцип работы итератора. Работу счетчиков в их простом варианте можно описать так: значение увеличивается на единицу, как только заканчивается каждая итерация. Цикл завершится в момент, когда в итераторе будет достигнут определенный порог (целевое число повторений). Программа начинает отсчитывать с 0, но иногда – с 1. В теле цикла прописывается значение итератора, которое можно в процессе выполнения подпрограммы сравнивать с какими-либо другими показателями или прибавлять к ним. При этом изменение самого итератора обычно приводит к тому, что цикл перестает работать, итерации перестают повторяться.
Изменение функционирования алгоритма. Многие языки программирования позволяют задавать итератору другое поведение. Это значит, что алгоритм будет прибавлять к значению не 1, а, например, 2 или отнимать 1 при каждом завершении итерации вплоть до достижения 0. Необходимость в таком изменении встречается редко, обычно к нему не прибегают без острой необходимости.
Как может работать итерация при проходах по объекту
Многие языки программирования включают в себя специальные форматы циклов, которые предназначены для обработки массивов и прочих итерируемых объектов.
Подобные циклы отличаются от стандартных тем, что итератор в них работает иначе: в процессе прохода он последовательно (от первого к последнему) принимает каждое значение из содержимого объекта. На практике это работает таким образом, как описано в примере ниже.
Пример: цикл предполагает проход по строке со словом «тетрадь». Итераций в итоге будет 7. Сначала итератор примет значение «т», затем «е» и так далее вплоть до «ь». Как только строка закончится, цикл завершится.
Подобный формат работы итератора удобен, когда нужно взаимодействовать с отдельными элементами, находящимися в более крупных единицах. В массиве может быть большое количество строк, каждую из которых нужно обработать отдельно. Именно для решения таких задач используется проход в рамках цикла. Обратите внимание, что возможность так делать есть только при работе с итерируемыми объектами.
В чем преимущества итераций при разработке
Повторения в программировании – распространенное явление, которое пользуется популярностью по нескольким причинам.
Итерации используют мало памяти
По сравнению с остальными структурами программирования, для реализации повторения нужно меньше памяти. В рекурсивном программировании применяются структуры стека, которые предполагают, что для ввода код каждый раз будет вызывать переменные входные данные. Получается, что для каждого возвращения к входному стеку программе понадобится очень много оперативной памяти.
В то же время итерация применяет структуру очереди, в которой содержатся сценарии кодирования для входа и выхода из цикла. Программа не требует затратных операций, в ней отсутствуют постоянные вызовы к служебному стеку кода, как следствие, нужны меньшие объемы памяти для корректной работы.
Итерации облегчают оптимизацию
Благодаря повторениям удается оптимизировать работу облачных сервисов и онлайн-приложений. Это позволяет улучшить пользовательский опыт и ускорить загрузку. Например, итерации используются, когда нужно автоматически заполнить платежные данные покупателя при покупке из-под авторизованной учетной записи.
Итерации отвечают за автоматизацию
Разработчики могут упростить свою работу за счет внедрения итераций в участки, где не нужно участие человека. Например, нередко в бизнес-сфере и при создании ПО их применяют для поиска данных в различных базах.
Примеры задач, которые решаются итеративно
Существует набор задач, которые традиционно решаются с применением итераций. Перечислим некоторые из них.
Циклический подсчет. Это может быть операция с математическими выражениями. Так, итерации помогают вычислять факториал или конкретное число Фибоначчи. Для решения подобных задач подходит и рекурсивный метод, но он требует несравнимо больше ресурсов.
Перебор. Для этого примера рассмотрим упрощенную схему: сервер предоставил объемный массив строк, каждая из которых представляет информацию о продукте с сайта интернет-магазина. Для выполнения некой задачи нужно найти в этих строках определенный повторяющийся элемент и перенести его в другое место. Чтобы достичь этой цели, можно использовать итеративный алгоритм, для этого есть все необходимые условия: массив – итерируемый объект, все его элементы пронумерованы, обойти их можно с помощью цикла.
Подсчет времени до выполнения условия. Простой пример: имеется статистика по приросту пользователей на сайте (A), нужно выяснить, через какой промежуток времени аудитория достигнет определенного значения (B) при таких же темпах увеличения. В этом случае разработчик не знает, сколько итераций потребуется, поэтому пишет цикл с незаданным числом повторений. Он выполняется раз за разом, пока верно или неверно условие (достигнуто или не достигнуто значение B), в это же время итератор с каждым шагом увеличивается на 1, отражая месяцы. Останется написать код так, чтобы программа после остановки цикла выдавала показатель счетчика – это и будет требуемый промежуток времени.
В чем отличия итерации от рекурсии
Итерация не является единственным повторяющимся алгоритмом, кроме нее существует, например, рекурсия, которая работает по другому принципу. Два принципиальных различия между ними:
- подпрограмма в итеративном подходе вызывается, завершается и вызывается снова несколько раз, при этом запускается она извне;
- подпрограмма в рекурсивном подходе вызывает сама себя и позволяет таким образом запускать сразу несколько вложенных друг в друга подпрограмм.
В рекурсии, когда одни аргументы отвечают искомым параметрам, функция отдает значение в предыдущий экземпляр подпрограммы и закрывается. Постепенно все процессы завершаются от внутренних к внешним, но такой подход требует большого количества памяти. На этом фоне итерации выглядят более предпочтительным вариантом.
Циклы и итерации
Циклы — простой способ сделать какое-то действие несколько раз. Эта глава руководства JavaScript Guide познакомит вас с различными операторами доступными в JavaScript.
Вы можете представить цикл в виде компьютеризированной версии игры, где вы говорите кому-то сделать X шагов в одном направлении, затем Y шагов в другом; для примера, идея игры «Иди 5 шагов на восток» может быть выражена в виде цикла:
var step; for (step = 0; step 5; step++) // Запускается 5 раз, с шагом от 0 до 4. console.log("Идём 1 шаг на восток"); >
Существует множество различных видов циклов, но все они по сути делают тоже самое: повторяют какое-либо действие несколько раз (не забывайте про нулевой раз повторения, отсчёт в массиве начинается с 0). Различные по строению циклы предлагают разные способы для определения начала и окончания цикла. Для различных задач программирования существуют свои операторы цикла, с помощью которых они решаются намного проще.
Операторы предназначенные для организации циклов в JavaScript:
Цикл for
Цикл for повторяет действия, пока не произойдёт какое-либо специальное событие завершения цикла. Оператор for в JavaScript аналогичен оператору for в Java и C. Объявление оператора for выглядит следующим образом:
for ([начало]; [условие]; [шаг]) выражения
При его выполнении происходит следующее:
- Выполняется выражение начало , если оно указано. Это выражение обычно инициализирует один или несколько счётчиков, но синтаксис позволяет выражению быть любой сложности. Также используется для объявления переменных.
- Выполняется условие . Если условие истинно, то выполняются выражения . Если оно ложно, цикл for прерывается. Если же условие полностью пропущено, то оно считается истинным.
- Выполняются выражения . Чтобы выполнить несколько выражений, используются блок-выражение < . >для группировки выражений.
- Обновляется шаг , если он есть, а затем управление возвращается к шагу 2.
Пример
form name="selectForm"> p> label for="musicTypes" >Выберите некоторые жанры музыки, а затем нажмите на кнопку ниже:label > select id="musicTypes" name="musicTypes" multiple="multiple"> option selected="selected">R&Boption> option>Jazzoption> option>Bluesoption> option>New Ageoption> option>Classicaloption> option>Operaoption> select> p> p>input id="btn" type="button" value="Как много выбрано?" />p> form> script> function howMany(selectObject) var numberSelected = 0; for (var i = 0; i selectObject.options.length; i++) if (selectObject.options[i].selected) numberSelected++; > > return numberSelected; > var btn = document.getElementById("btn"); btn.addEventListener("click", function () alert("Выбрано элементов: " + howMany(document.selectForm.musicTypes)); >); script>
Цикл do. while
Цикл do. while повторяется пока заданное условие истинно. Оператор do. while имеет вид:
do выражения while (условие);
выражения выполняются пока условие истинно. Чтобы использовать несколько выражений, используйте блок-выражение < . >, чтобы сгруппировать их. Если условие истинно, выражения выполнятся снова. В конце каждого прохода условие проверяется. Если условие ложно, выполнение приостанавливается и управление передаётся выражению после do. while .
Пример
В следующем примере, цикл do выполнится минимум 1 раз и запускается снова, пока i меньше 5.
do i += 1; console.log(i); > while (i 5);
Цикл while
Цикл while выполняет выражения пока условие истинно. Выглядит он так:
while (условие) выражения
Если условие становится ложным, выражения в цикле перестают выполняться и управление переходит к выражению после цикла.
Условие проверяется на истинность до того, как выполняются выражения в цикле. Если условие истинно, выполняются выражения , а затем условие проверяется снова. Если условие ложно, выполнение приостанавливается и управление переходит к выражению после while .
Чтобы использовать несколько выражений, используйте блок выражение < . >, чтобы сгруппировать их.
Пример 1
Следующий цикл while работает, пока n меньше трёх:
var n = 0; var x = 0; while (n 3) n++; x += n; >
С каждой итерацией, цикл увеличивает n и добавляет это значение к x . Поэтому, x и n получают следующие значения:
- После первого прохода: n = 1 и x = 1
- После второго: n = 2 и x = 3
- После третьего прохода: n = 3 и x = 6
Пример 2
Избегайте бесконечных циклов. Убедитесь, что условие цикла в итоге станет ложным; иначе, цикл никогда не прервётся. Выражения в следующем цикле while будут выполняться вечно, т.к. условие никогда не станет ложным:
while (true) console.log("Hello, world"); >
Метка (label)
Метка представляет собой оператор с идентификатором, который позволяет вам ссылаться на какое-то место в вашей программе. Например, вы можете использовать метку, чтобы обозначить цикл, а затем использовать операторы break или continue , чтобы указать, должна ли программа прерывать цикл или продолжать его выполнение.
Синтаксис метки следующий:
метка : оператор
Значение метки может быть любым корректным JavaScript идентификатором, не являющимся зарезервированным словом. Оператор , указанный вами после метки может быть любым выражением.
Пример
В этом примере, метка markLoop обозначает цикл while .
markLoop: while (theMark == true) doSomething(); >
break
Используйте оператор break , чтобы прерывать цикл, переключать управление или в сочетании с оператором метка.
- Когда вы используете break без метки, он прерывает циклы while , do-while и for или сразу переключает управление к следующему выражению.
- Когда вы используете break с меткой, он прерывает специально отмеченное выражение.
Синтаксис оператора может быть таким:
Первая форма синтаксиса прерывает цикл совсем или переключает управление; вторая прерывает специально обозначенное выражение.
Пример 1
Следующий пример проходит по элементам в массиве, пока не найдёт элемент, чьё значение — theValue :
for (i = 0; i a.length; i++) if (a[i] == theValue) break; > >
Пример 2: Прерывание метки
var x = 0; var z = 0; labelCancelLoops: while (true) console.log("Внешний цикл: " + x); x += 1; z = 1; while (true) console.log("Внутренний цикл: " + z); z += 1; if (z === 10 && x === 10) break labelCancelLoops; > else if (z === 10) break; > > >
continue
Оператор continue используется, чтобы шагнуть на шаг вперёд в циклах while , do-while , for или перейти к метке.
- Когда вы используете continue без метки, он прерывает текущую итерацию циклов while , do-while и for и продолжает выполнение цикла со следующей итерации. В отличие от break , continue не прерывает выполнение цикла полностью. В цикле while он прыгает к условию. А в for увеличивает шаг .
- Когда вы используете continue с меткой, он применяется к циклу с этой меткой.
Синтаксис continue может выглядеть так:
- continue;
- continue Метка ;
Пример 1
Следующий пример показывает цикл while с оператором continue , который срабатывает, когда значение i равно 3. Таким образом, n получает значения 1, 3, 7 и 12.
var i = 0; var n = 0; while (i 5) i++; if (i == 3) continue; > n += i; >
Пример 2
Выражение, отмеченное checkiandj содержит выражение отмеченное checkj . При встрече с continue , программа прерывает текущую итерацию checkj и начинает следующую итерацию. Каждый раз при встрече с continue , checkj переходит на следующую итерацию, пока условие возвращает false . Когда возвращается false , после вычисления остатка от деления checkiandj , checkiandj переходит на следующую итерацию, пока его условие возвращает false . Когда возвращается false , программа продолжает выполнение с выражения после checkiandj .
Если у continue проставлена метка checkiandj , программа может продолжиться с начала метки checkiandj .
checkiandj: while (i 4) console.log(i); i += 1; checkj: while (j > 4) console.log(j); j -= 1; if (j % 2 != 0) continue checkj; > console.log(j + " чётное."); > console.log("i token operator">+ i); console.log("j token operator">+ j); >
for. in
Оператор for. in проходит по всем перечислимым свойствам объекта. JavaScript выполнит указанные выражения для каждого отдельного свойства. Цикл for. in выглядит так:
for (variable in object)
Пример
Следующая функция берёт своим аргументом объект и его имя. Затем проходит по всем свойствам объекта и возвращает строку, которая содержит имена свойств и их значения.
function dump_props(obj, obj_name) var result = ""; for (var i in obj) result += obj_name + "." + i + " token operator">+ obj[i] + "
"; > result += "
"; return result; >
Для объекта car со свойствами make и model , результатом будет:
.make = Ford; car.model = Mustang;
Пример №2
Также, по ключу можно выводить значение:
let obj = for (key in obj) < console.log(`$= $`); > // model = AUDI A8 // year = 2019 // color = brown
Массивы
Хотя, очень заманчиво использовать for. in как способ пройтись по всем элементам Array , этот оператор возвращает имя свойств определённых пользователем помимо числовых индексов. Таким образом лучше использовать стандартный for для числовых индексов при взаимодействии с массивами, поскольку оператор for. in проходит по определённым пользователем свойствам в дополнение к элементам массива, если вы изменяете массив, например, добавляете свойства и методы.
Пример
let arr = ['AUDI A8', '2019', 'brown']; arr.cost = '$100.000'; for (key in arr) < console.log(`$= $`); > // 0 = AUDI A8 // 1 = 2019 // 2 = brown // cost = $100.000
for. of
Оператор for. of создаёт цикл, проходящий по перечислимым объектам (en-US) (включая Array , Map (en-US), Set , объект arguments (en-US) и так далее), вызывая на каждой итерации функцию с выражениями, которые надо выполнить для получения значения каждого отдельного свойства.
for (variable of object)
Следующий пример показывает разницу между циклами for. of и for. in . Тогда как for. in проходит по именам свойств, for. of проходит по значениям свойств:
let arr = [3, 5, 7]; arr.foo = "hello"; for (let i in arr) console.log(i); // выводит "0", "1", "2", "foo" > for (let i of arr) console.log(i); // выводит "3", "5", "7" >
- « Предыдущая статья
- Следующая статья »
Found a content problem with this page?
- Edit the page on GitHub.
- Report the content issue.
- View the source on GitHub.
This page was last modified on 7 авг. 2023 г. by MDN contributors.
Your blueprint for a better internet.
Циклы while и for
При написании скриптов зачастую встаёт задача сделать однотипное действие много раз.
Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
Для многократного повторения одного участка кода предусмотрены циклы.
Циклы for…of и for…in
Небольшое объявление для продвинутых читателей.
В этой статье рассматриваются только базовые циклы: while , do..while и for(..;..;..) .
Если вы пришли к этой статье в поисках других типов циклов, вот указатели:
- См. for…in для перебора свойств объекта.
- См. for…of и Перебираемые объекты для перебора массивов и перебираемых объектов.
В противном случае, продолжайте читать.
Цикл «while»
Цикл while имеет следующий синтаксис:
while (condition) < // код // также называемый "телом цикла" >
Код из тела цикла выполняется, пока условие condition истинно.
Например, цикл ниже выводит i , пока i < 3 :
let i = 0; while (i < 3) < // выводит 0, затем 1, затем 2 alert( i ); i++; >
Одно выполнение тела цикла по-научному называется итерация. Цикл в примере выше совершает три итерации.
Если бы строка i++ отсутствовала в примере выше, то цикл бы повторялся (в теории) вечно. На практике, конечно, браузер не позволит такому случиться, он предоставит пользователю возможность остановить «подвисший» скрипт, а JavaScript на стороне сервера придётся «убить» процесс.
Любое выражение или переменная может быть условием цикла, а не только сравнение: условие while вычисляется и преобразуется в логическое значение.
Например, while (i) – более краткий вариант while (i != 0) :
let i = 3; while (i) < // когда i будет равно 0, условие станет ложным, и цикл остановится alert( i ); i--; >
Фигурные скобки не требуются для тела цикла из одной строки
Если тело цикла состоит лишь из одной инструкции, мы можем опустить фигурные скобки :
let i = 3; while (i) alert(i--);
Цикл «do…while»
Проверку условия можно разместить под телом цикла, используя специальный синтаксис do..while :
do < // тело цикла >while (condition);
Цикл сначала выполнит тело, а затем проверит условие condition , и пока его значение равно true , он будет выполняться снова и снова.
let i = 0; do < alert( i ); i++; >while (i < 3);
Такая форма синтаксиса оправдана, если вы хотите, чтобы тело цикла выполнилось хотя бы один раз, даже если условие окажется ложным. На практике чаще используется форма с предусловием: while(…) .
Цикл «for»
Более сложный, но при этом самый распространённый цикл — цикл for .
Выглядит он так:
for (начало; условие; шаг) < // . тело цикла . >
Давайте разберёмся, что означает каждая часть, на примере. Цикл ниже выполняет alert(i) для i от 0 до (но не включая) 3 :
for (let i = 0; i < 3; i++) < // выведет 0, затем 1, затем 2 alert(i); >
Рассмотрим конструкцию 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 >
Можно убрать и шаг :
let i = 0; for (; i
Это сделает цикл аналогичным 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 , чтобы выводить только нечётные значения:
for (let i = 0; i < 10; i++) < // если true, пропустить оставшуюся часть тела цикла if (i % 2 == 0) continue; alert(i); // 1, затем 3, 5, 7, 9 >
Для чётных значений i , директива continue прекращает выполнение тела цикла и передаёт управление на следующую итерацию for (со следующим числом). Таким образом alert вызывается только для нечётных значений.
Директива continue позволяет избегать вложенности
Цикл, который обрабатывает только нечётные значения, мог бы выглядеть так:
for (let i = 0; i < 10; i++) < if (i % 2) < alert( i ); >>
С технической точки зрения он полностью идентичен. Действительно, вместо continue можно просто завернуть действия в блок if .
Однако мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри if более длинный, то это ухудшает читаемость, в отличие от варианта с continue .
Нельзя использовать break/continue справа от оператора „?“
Обратите внимание, что эти синтаксические конструкции не являются выражениями и не могут быть использованы с тернарным оператором ? . В частности, использование таких директив, как break/continue , вызовет ошибку.
Например, если мы возьмём этот код:
if (i > 5) < alert(i); >else
…и перепишем его, используя вопросительный знак:
(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 лишь прервёт внутренний цикл, но этого недостаточно. Достичь желаемого поведения можно с помощью меток.
Метка имеет вид идентификатора с двоеточием перед циклом:
labelName: for (. )
Вызов 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('Готово!') .
Можно размещать метку на отдельной строке:
outer: for (let i = 0; i
Директива continue также может быть использована с меткой. В этом случае управление перейдёт на следующую итерацию цикла с меткой.
Метки не позволяют «прыгнуть» куда угодно
Метки не дают возможности передавать управление в произвольное место кода.
Например, нет возможности сделать следующее:
break label; // не прыгает к метке ниже label: for (. )
Директива break должна находиться внутри блока кода. Технически, подойдет любой маркированный блок кода, например:
label: < // . break label; // работает // . >
…Хотя в 99.9% случаев break используется внутри циклов, как мы видели в примерах выше.
К слову, continue возможно только внутри цикла.
Итого
Мы рассмотрели 3 вида циклов:
- while – Проверяет условие перед каждой итерацией.
- do..while – Проверяет условие после каждой итерации.
- for (;;) – Проверяет условие перед каждой итерацией, есть возможность задать дополнительные настройки.
Чтобы организовать бесконечный цикл, используют конструкцию while (true) . При этом он, как и любой другой цикл, может быть прерван директивой break .
Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву continue .
Обе этих директивы поддерживают метки, которые ставятся перед циклом. Метки – единственный способ для break/continue выйти за пределы текущего цикла, повлиять на выполнение внешнего.
Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.