Для более гибкого управления циклом используются директивы break и continue.
Выход: break
Выйти из цикла можно не только при проверке условия но и, вообще, в любой момент. Эту возможность обеспечивает директива break.
Например, бесконечный цикл в примере прекратит выполнение при i==5:
var i=0;
while(1) {
i++;
*!*if (i==5) break;*/!*
alert(i);
}
alert('Последняя i = '+ i ); // 5 (*)
Выполнение продолжится со строки (*), следующей за циклом.
Следующая итерация: continue
Директива continue прекращает выполнение текущей итерации цикла. Например, цикл ниже не выводит четные значения:
for (var i = 0; i < 10; i++) {
*!*if (i % 2 == 0) continue;*/!*
alert(i);
}
Для четных i срабатывает continue, выполнение блока прекращается и управление передается на for.
Как правило, continue и используют, чтобы не обрабатывать определенные значения в цикле.
Цикл, который обрабатывает только часть значений, мог бы выглядеть так:
for (var i = 0; i < 10; i++) {
if ( checkValue(i) ) {
// функция checkValue проверяет, подходит ли i
// ...
// ... обработка
// ... этого
// ... значения
// ... цикла
// ...
}
}
Все хорошо, но мы получили дополнительный уровень вложенности фигурных скобок, без которого можно и нужно обойтись.
Гораздо лучше здесь использовать continue:
for (var i = 0; i < 10; i++) {
*!*if ( !checkValue(i) ) continue;*/!*
// здесь мы точно знаем, что i подходит
// ...
// ... обработка
// ... этого
// ... значения
// ... цикла
// ...
}
Обычно мы можем заменить if на оператор вопросительный знак '?'.
То есть, запись:
if (условие) {
a();
} else {
b();
}
..Аналогична записи:условие ? a() : b();
В обоих случаях в зависимости от условия выполняется либо a() либо b().
Но разница состоит в том, что оператор вопросительный знак '?', использованный во второй записи, возвращает значение.
Синтаксические конструкции, которые не дают значения, нельзя использовать справа от '?'. К таким относятся большинство конструкций и, в частности, break/continue.
Поэтому такой код приведёт к ошибке:
(i > 5) ? alert(i) : *!*continue*/!*;Так что нельзя сказать, что вопросительный знак может всегда заменить простой
if.
Метки
Бывает нужно выйти одновременно из нескольких уровней цикла.
Например, надо ввести значения в точках с координатами, вот так:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var input = prompt('Значение в координатах '+i+','+j, '');
if (input == null) *!*break*/!*; // (*)
}
}
alert('Готово!');
Обычный вызов break в строке (*) не может прервать два цикла сразу. Для этого существуют метки.
Метка имеет вид "имя:", имя должно быть уникальным. Она ставится перед циклом, вот так:
outer: for (var i = 0; i < 3; i++) { ... }
Можно также выносить ее на отдельную строку. Вызов break outer прерывает управление цикла с такой меткой, вот так:
outer:
for (var i = 0; i < 3; i++) {
for (var j = 0; j < 3; j++) {
var input = prompt('Значение в координатах '+i+','+j, '');
if (input == null) *!*break outer*/!*; // (*)
}
}
alert('Готово!');
Директива continue также может быть использована с меткой. Управление перепрыгнет на следующую итерацию цикла с меткой.
Метки можно ставить в том числе на блок, без цикла:
my: {
for (;;) {
for (i=0; i<10; i++) {
if (i>4) break my;
}
}
some_code;
}
alert("После my"); // (*)
В примере выше, break перепрыгнет через some_code, выполнение продолжится сразу после блока my, со строки (*). Возможность ставить метку на блоке используется редко. Обычно метки ставятся перед циклом.
В некоторых языках программирования есть оператор goto, который может передавать управление на любой участок программы.
Операторы break/continue более ограниченны. Они работают только внутри циклов, и метка должна быть не где угодно, а выше по уровню вложенности.
В JavaScript нет goto.
Натуральное число, большее 1, называется простым, если оно ни на что не делится, кроме себя и 1.
Другими словами, n>1 - простое, если при делении на любое число от 2 до n-1 есть остаток.
Создайте код, который перебирает все числа от 2 до 10, и выводит только простые. Результат должен быть: 2,3,5,7.
P.S. Код также должен работать для 100, 1000 и любых других значений вместо 10.
Для всех i от 1 до 10 {
Для всех чисел j от 2 до i {
если i делится на j без остатка - continue цикла по i
}
если мы дошли до этой строки, то i - простое число
}
Решение с использованием метки:
nextPrime:
for(var i=2; i<10; i++) {
for(var j=2; j<i; j++) {
if ( i % j == 0) continue nextPrime;
}
alert(i); // простое
}
Конечно же, его можно оптимизировать с точки зрения производительности. Например, проверять все j не от 2 до i, а от 2 до квадратного корня из i. А ещё лучше — использовать более эффективные специализированные алгоритмы проверки простоты числа. Но здесь мы этого делать не будем ![]()
Комментарии
- Приветствуются комментарии, содержащие дополнения и вопросы по статье, и ответы на них.
- Если ваш комментарий касается задачи -- откройте её в отдельном окне и напишите там.
- Комментарии без смысла, с рекламой или не о статье вообще - удаляются.