Урок 5. Циклы: for, while и for...of
Цикл повторяет блок кода, пока выполняется условие. Без циклов, чтобы вывести числа от 1 до 100, пришлось бы написать сто строк console.log. С циклом — три.
Цикл for
for (let i = 1; i <= 5; i++) {
console.log("Шаг " + i);
}Шаг 1
Шаг 2
Шаг 3
Шаг 4
Шаг 5В скобках после for — три части через точку с запятой:
let i = 1— начало: выполняется один раз, до цикла. Обычно здесь заводят счётчик.i <= 5— условие: проверяется перед каждым повтором. Пока оно верно, тело цикла выполняется.i++— шаг: выполняется после каждого повтора, здесь счётчик растёт на единицу.
Один проход тела цикла называют итерацией. Счётчик i объявлен через let и существует только внутри цикла: после цикла имени i нет.
Сумма чисел от 1 до 100 — классическая задача на цикл:
let sum = 0;
for (let i = 1; i <= 100; i++) {
sum += i;
}
console.log(sum);5050Счётчик может идти и в обратную сторону, и с любым шагом: for (let i = 10; i > 0; i -= 2) даёт 10, 8, 6, 4, 2.
Цикл while
while повторяет тело, пока условие верно. Он удобен, когда заранее неизвестно, сколько будет повторов. Например: сколько раз нужно удвоить единицу, чтобы получить больше тысячи?
let n = 1;
let steps = 0;
while (n <= 1000) {
n *= 2;
steps++;
}
console.log(n, steps);1024 10Условие проверяется до каждого прохода. Если оно неверно с самого начала, тело не выполнится ни разу.
Цикл do … while проверяет условие после прохода, поэтому тело выполняется хотя бы один раз:
let attempts = 0;
do {
attempts++;
console.log("Попытка " + attempts);
} while (attempts < 3);Попытка 1
Попытка 2
Попытка 3Бесконечный цикл
Если условие никогда не станет ложным, цикл не закончится:
let i = 0;
while (i < 10) {
console.log(i);
// нет i++: i всегда 0, и цикл бесконечный
}Бесконечный цикл на странице «вешает» вкладку браузера: она перестаёт отвечать, и браузер через некоторое время предложит её закрыть. В Node.js программу останавливает Ctrl+C в терминале. Прежде чем запускать цикл, проверьте, что в нём меняется то, от чего зависит условие.
Перебор массива: for...of
Массив — список значений в квадратных скобках (подробно — в уроке Массивы и методы map, filter, reduce). Перебрать его элементы по очереди проще всего циклом for...of:
const fruits = ["яблоко", "груша", "слива"];
for (const fruit of fruits) {
console.log(fruit);
}яблоко
груша
сливаНа каждой итерации в fruit оказывается следующий элемент. Номер элемента здесь не нужен, и ошибиться в границах счётчика невозможно. Строку for...of перебирает по символам: for (const ch of "JS") даст J, потом S.
Если номер всё же нужен — подойдёт обычный for. Номера элементов массива начинаются с нуля, а последний номер на единицу меньше длины fruits.length:
const fruits = ["яблоко", "груша", "слива"];
for (let i = 0; i < fruits.length; i++) {
console.log(i + 1 + ". " + fruits[i]);
}1. яблоко
2. груша
3. сливаЧастая ошибка — i <= fruits.length: на последнем шаге fruits[3] не существует, и в выводе появится undefined.
Есть ещё цикл for...in. Он перебирает не значения, а имена свойств объекта. Для массивов его не берут — только for...of. Как перебирать объекты, рассказано в уроке Объекты и JSON.
break и continue
breakпрерывает цикл целиком.continueпропускает остаток текущей итерации и переходит к следующей.
Первое число больше 50, которое делится на 7:
for (let i = 51; i < 100; i++) {
if (i % 7 === 0) {
console.log("Нашлось: " + i);
break;
}
}Нашлось: 56Только нечётные числа от 1 до 9:
for (let i = 1; i <= 9; i++) {
if (i % 2 === 0) {
continue;
}
console.log(i);
}1
3
5
7
9Вложенные циклы
Цикл может стоять внутри другого цикла. Внутренний проходит целиком на каждой итерации внешнего. Так строится таблица умножения:
for (let i = 1; i <= 3; i++) {
let row = "";
for (let j = 1; j <= 4; j++) {
row += String(i * j).padStart(4);
}
console.log(row);
} 1 2 3 4
2 4 6 8
3 6 9 12padStart(4) дополняет строку пробелами слева до четырёх символов — так столбцы выравниваются. Во вложенных циклах счётчики называют по-разному (i и j), иначе внутренний цикл испортит значение внешнего.
Какой цикл выбрать
| Задача | Цикл |
|---|---|
| Перебрать все элементы массива или символы строки | for...of |
| Повторить известное число раз, нужен номер | for |
| Повторять, пока не выполнится условие | while |
| Выполнить хотя бы один раз, потом проверить | do...while |
У массивов есть и свои методы перебора — forEach, map, filter. Часто они заменяют цикл одной строкой; о них — в уроке о массивах.
Коротко
for (начало; условие; шаг)— цикл со счётчиком;i++увеличивает счётчик на единицу.whileпроверяет условие перед проходом,do...while— после.for...ofперебирает элементы массива и символы строки.breakпрерывает цикл,continueпереходит к следующей итерации.- Номера элементов массива — от
0доlength - 1; условие —i < arr.length.