Для более гибкого управления циклом используются директивы break и continue.
Выход: break
Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива break.
Например, бесконечный цикл в примере прекратит выполнение при i==5:
11 |
alert('Последняя i = '+ i ); |
Выполнение продолжится со строки (*), следующей за циклом.
Следующая итерация: continue
Директива continue прекращает выполнение текущей итерации цикла. Например, цикл ниже не выводит четные значения:
Для четных i срабатывает continue, выполнение блока прекращается и управление передается наfor.
Как правило, continue и используют, чтобы не обрабатывать определенные значения в цикле.
Цикл, который обрабатывает только часть значений, мог бы выглядеть так:
01 |
for (var i = 0; i < 10; i++) { |
03 |
if ( checkValue(i) ) { |
Все хорошо, но мы получили дополнительный уровень вложенности фигурных скобок, без которого можно и нужно обойтись.
Гораздо лучше здесь использовать continue:
01 |
for (var i = 0; i < 10; i++) { |
03 |
if ( !checkValue(i) ) continue; |
Обычно мы можем заменить if на оператор вопросительный знак '?'.
То есть, запись:
..Аналогична записи:
В обоих случаях в зависимости от условия выполняется либо a() либо b().
Но разница состоит в том, что оператор вопросительный знак '?', использованный во второй записи, возвращает значение.
Синтаксические конструкции, которые не возвращают значений, нельзя использовать в операторе '?'. К таким относятся большинство конструкций и, в частности, break/continue.
Поэтому такой код приведет к ошибке:
(i > 5) ? alert(i) : continue; |
Метки
Бывает нужно выйти одновременно из нескольких уровней цикла.
Представим, что нужно ввести значения точек. У каждой точки есть две координаты (i, j). Цикл для ввода значений i,j = 0..2 может выглядеть так:
Здесь break используется, чтобы прервать ввод, если посетитель нажал на Отмена. Но обычный вызовbreak в строке (*) не может прервать два цикла сразу. Как же прервать ввод полностью? Один из способов — поставить метку.
Метка имеет вид "имя:", имя должно быть уникальным. Она ставится перед циклом, вот так:
outer: for (var i = 0; i < 3; i++) { ... } |
Можно также выносить ее на отдельную строку. Вызов break outer прерывает управление цикла с такой меткой, вот так:
Директива continue также может быть использована с меткой. Управление перепрыгнет на следующую итерацию цикла с меткой.
Метки можно ставить в том числе на блок, без цикла:
В примере выше, break перепрыгнет через some_code, выполнение продолжится сразу после блока my, со строки (*). Возможность ставить метку на блоке используется редко. Обычно метки ставятся перед циклом.
В некоторых языках программирования есть оператор goto, который может передавать управление на любой участок программы.
Операторы break/continue более ограниченны. Они работают только внутри циклов, и метка должна быть не где угодно, а выше по уровню вложенности.
В JavaScript нет goto.
Важность: 4
1 |
Для всех i от 1 до 10 { |
2 |
проверить, делится ли число i на какое-либо из чисел до него |
3 |
если делится, то это i не подходит, берем следующее |
4 |
если не делится, то i - простое число |
Решение с использованием метки:
Конечно же, его можно оптимизировать с точки зрения производительности. Например, проверять все j не от 2 до i, а от 2 до квадратного корня из i. А для очень больших чисел — существуют более эффективные специализированные алгоритмы проверки простоты числа, например квадратичное решето и решето числового поля.
Комментарии
Оставить комментарий
Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)
Термины: Выполнение скриптов на стороне клиента JavaScript, jqvery, JS фреймворки (Frontend)