Цикл for...of

Цикл for...of

Технический фундамент for...of

for...of - это высокоуровневый цикл поверх протокола итерации (Symbol.iterator), который получает последовательность значений без ручного управления индексом. Он работает только с итерируемыми структурами и скрывает низкоуровневые вызовы итератора.

Ключевой момент: for...of берет значения из итератора, а не ключи и не индексы.

Проверь себя: почему for...of особенно удобен, когда индекс тебе не нужен?

Базовый синтаксис

for (const item of iterable) {
  // работа с item
}

Пример с массивом:

const scores = [55, 72, 90];

for (const score of scores) {
  console.log(score);
}

Смотри, что важно: переменная score в каждой итерации содержит текущее значение.

for...of со строкой

const word = 'JS';

for (const ch of word) {
  console.log(ch);
}

Цикл проходит по символам строки, что полезно в задачах валидации и подсчета.

for...of с Set и Map

const tags = new Set(['js', 'ts']);
for (const tag of tags) {
  console.log(tag);
}

const pairs = new Map([
  ['a', 1],
  ['b', 2],
]);
for (const [key, value] of pairs) {
  console.log(key, value);
}

Здесь часто путаются: в Map на каждой итерации приходит пара [key, value].

Проверь себя: почему в Map удобно сразу использовать деструктуризацию?

Мини-сценарий: подсчет прошедших

const results = [40, 78, 81, 69];
let passed = 0;

for (const score of results) {
  if (score >= 70) passed++;
}

console.log(passed); // 2

Это типичная задача аналитики/отчетности, где индекс не нужен вовсе.

break и continue

for...of поддерживает те же управляющие операторы.

for (const score of results) {
  if (score < 0) break;
  if (score < 70) continue;
  console.log('passed:', score);
}

Смотри, что важно: логика потока читается так же, как в обычном for.

Дополнительный пример для новичка: накопление результата

const words = ['js', 'loop', 'code'];
let totalLength = 0;

for (const word of words) {
  totalLength += word.length;
}

console.log(totalLength); // 10

Этот шаблон показывает типичный сценарий for...of: пройти по значениям и аккумулировать итог без работы с индексами.

Частые ошибки новичков

  • Пытаться получить индекс напрямую из for...of.
  • Использовать for...of на обычном объекте {}.
  • Путать for...of (значения) с for...in (ключи).
  • Слишком усложнять цикл, где лучше вынести часть логики в функцию.

Анти-провал: если тебе нужен индекс и значение, используй for или array.entries().

for (const [index, score] of results.entries()) {
  console.log(index, score);
}

Что будет, если изменить входные данные

Если results пустой, цикл просто не выполнится - это корректно. Если в массив попадет undefined, условие score >= 70 даст false, но для надежности можно добавить фильтрацию типа до сравнения.

Проверь себя: как проверить, что элемент действительно число внутри цикла?

Краткий итог

  • for...of - удобный цикл для итерируемых структур без работы с индексом.
  • Он делает код чище и снижает риск ошибок на границах массива.
  • Поддерживает break/continue и хорошо сочетается с деструктуризацией.
  • Не подходит для обычных объектов без преобразования.
  • Выбирай for...of, когда важны значения элементов, а не их позиции.