Перейти к содержимому
Теория · Условия и циклы · урок 7 из 13

Цикл for…of

Представьте список покупок: молоко, хлеб, яблоки. В магазине вы идёте по нему сверху вниз и берёте каждый пункт по очереди. Номер пункта вам не нужен, важен сам пункт. Когда пункты кончились, покупки закончены.

Цикл со счётчиком перебирает числа. Чтобы пройти по значениям, например по буквам слова или по пунктам списка, есть цикл for…of. Он сам берёт значения по порядку и останавливается, когда они кончились, поэтому ни счётчик, ни условие ему не нужны:

JavaScript
const colors = ["red", "green", "blue"];

for (const color of colors) {
    console.log(color);
}
// red
// green
// blue

Массив

Значения в квадратных скобках через запятую образуют массив — упорядоченный список. Каждое значение в нём называют элементом, а номер элемента называют индексом. В массиве colors три элемента.

Индексы считают с 0: у "red" индекс 0, у "green" — 1, у "blue" — 2. Здесь список покупок расходится с массивом: пункты списка обычно нумеруют с единицы, а элементы массива — с нуля.

Цикл for…of

for…of перебирает и массивы, и строки. Разберём оба случая.

По массиву

Давайте пройдём по первой программе:

  1. const colors = ["red", "green", "blue"] создаёт массив из трёх элементов.
  2. На первой итерации color получает "red", и тело выводит red.
  3. На следующих итерациях color получает "green", а затем "blue".
  4. Элементы кончились, и цикл останавливается сам.

По пустому массиву [] тело цикла не выполняется ни разу.

На каждой итерации for…of создаёт новую переменную и кладёт в неё очередной элемент. Внутри итерации переменная не меняется, поэтому её объявляют через const. В цикле со счётчиком так нельзя: шаг i++ меняет переменную, и там нужен let.

По строке

Строку for…of перебирает по символам. Эта программа считает буквы a в слове:

JavaScript
let count = 0;

for (const ch of "banana") {
    if (ch === "a") {
        count++;
    }
}

console.log(count); // 3

Переменная ch по очереди получает значения "b", "a", "n" и так далее. На каждой букве a условие истинно, и счётчик растёт на единицу.

Внутри for…of работают break и continue, как в цикле со счётчиком.

Сумма элементов

Самая частая работа для for…of — собрать из элементов один результат. Вернёмся к магазину: на кассе вы складываете цены всех покупок по очереди. Программа делает то же самое:

JavaScript
const prices = [120, 45, 300];
let total = 0;

for (const price of prices) {
    total += price;
}

console.log(total); // 465

Давайте разберём по шагам:

  1. До цикла total равен 0: в корзине ещё ничего не посчитано.
  2. На первой итерации price получает 120, и total становится 120.
  3. Затем price получает 45, и total становится 165.
  4. На последней итерации price равен 300, и total становится 465.

Переменную total объявляют через let и до цикла. Объявленная в теле цикла, она создавалась бы заново с нулём на каждой итерации, а после цикла её не было бы видно.

Частая ошибка

Переменной цикла присвоили новое значение, чтобы изменить элемент массива:

JavaScript
const prices = [120, 45, 300];

for (let price of prices) {
    price = price * 2; // ✗
}

console.log(prices); // [ 120, 45, 300 ]

Ошибки нет, но массив остался прежним. Цикл кладёт в price копию числа, и присваивание меняет только эту копию. В списке покупок это похоже на цену, переписанную на отдельном листке: на ценнике в магазине она не меняется.

Если нужен новый результат, накапливайте его в отдельной переменной, как total выше.

Главное

  • Массив — упорядоченный список элементов, и индексы его элементов начинаются с 0.
  • for…of перебирает значения: элементы массива или символы строки.
  • Переменную цикла объявляют через const: на каждой итерации она новая.
  • Новое значение переменной цикла не меняет массив; результат собирают в отдельной переменной.

Подпишись, чтобы пройти курс

Курс бесплатный. Войди через Telegram и подпишись на канал — откроются все уроки.

Войти другим способом