← Назад к вопросам

Когда применяется цикл for…of?

1.3 Junior🔥 91 комментариев
#JavaScript Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда применяется цикл for...of

for...of — это синтаксис цикла, который предназначен для итерирования по итерируемым объектам (iterable objects). Это один из самых удобных способов обхода данных в современном JavaScript. Ключевое отличие от других циклов — for...of работает только с объектами, которые реализуют протокол итератора.

Основной синтаксис

for (const element of iterable) {
  console.log(element);
}

Когда применяется for...of

1. Обход массивов

const numbers = [10, 20, 30, 40];

for (const num of numbers) {
  console.log(num);
}
// Вывод: 10, 20, 30, 40

// Сравнение с for и forEach
for (let i = 0; i < numbers.length; i++) {
  console.log(numbers[i]);
}

numbers.forEach((num) => {
  console.log(num);
});

for...of предпочтительнее forEach, если нужна возможность break и continue.

2. Обход строк

Строки в JavaScript тоже итерируемые:

const word = 'hello';

for (const char of word) {
  console.log(char);
}
// Вывод: h, e, l, l, o

// Полезно для работы с Unicode символами (в отличие от for loop)
const emoji = 'Hello😀';
for (const char of emoji) {
  console.log(char);
}
// Вывод корректно обрабатывает эмодзи

3. Обход Set и Map

Set:

const set = new Set([1, 2, 3, 3, 4]);

for (const value of set) {
  console.log(value);
}
// Вывод: 1, 2, 3, 4

Map:

const map = new Map([
  ['name', 'John'],
  ['age', 30],
  ['city', 'New York']
]);

for (const [key, value] of map) {
  console.log(`${key}: ${value}`);
}
// Вывод:
// name: John
// age: 30
// city: New York

// Можно итерировать только ключи или значения
for (const key of map.keys()) {
  console.log(key);
}

for (const value of map.values()) {
  console.log(value);
}

4. Обход результатов querySelectorAll

const elements = document.querySelectorAll('.item');

for (const element of elements) {
  element.classList.add('active');
}

5. Обход NodeList

const nodes = document.childNodes;

for (const node of nodes) {
  if (node.nodeType === Node.ELEMENT_NODE) {
    console.log(node.tagName);
  }
}

6. Итерирование по объектам с Symbol.iterator

Любой объект можно сделать итерируемым, реализовав Symbol.iterator:

const range = {
  from: 1,
  to: 5,
  [Symbol.iterator]() {
    return {
      current: this.from,
      last: this.to,
      next() {
        if (this.current <= this.last) {
          return { done: false, value: this.current++ };
        } else {
          return { done: true };
        }
      }
    };
  }
};

for (const value of range) {
  console.log(value);
}
// Вывод: 1, 2, 3, 4, 5

for...of vs for vs forEach vs map

const arr = [1, 2, 3];

// 1. Традиционный for — полный контроль, работает везде
for (let i = 0; i < arr.length; i++) {
  if (i === 1) break; // Можно прерывать
  console.log(arr[i]);
}

// 2. for...of — удобен, работает с итерируемыми, поддерживает break/continue
for (const value of arr) {
  if (value === 2) continue; // Пропускаем 2
  console.log(value);
}

// 3. forEach — функциональный подход, не работает break/continue
arr.forEach((value, index) => {
  console.log(value);
});

// 4. map — для трансформации массива, возвращает новый
const doubled = arr.map(x => x * 2);

Почему for...of лучше forEach

// for...of позволяет break и continue
for (const item of items) {
  if (item.skip) continue;
  if (item.stop) break;
  process(item);
}

// forEach не позволяет прерывать
items.forEach(item => {
  if (item.skip) return; // Только пропуск элемента, не цикла
  process(item);
});

Async iteration — for await...of

Для работы с асинхронными итераторами:

const asyncIterable = {
  [Symbol.asyncIterator]() {
    let count = 0;
    return {
      async next() {
        count++;
        await new Promise(resolve => setTimeout(resolve, 100));
        if (count <= 3) {
          return { value: count, done: false };
        }
        return { done: true };
      }
    };
  }
};

for await (const value of asyncIterable) {
  console.log(value);
}
// Вывод через 100ms каждый: 1, 2, 3

// Практический пример: получение данных из API с пагинацией
async function* fetchPages() {
  let page = 1;
  while (true) {
    const response = await fetch(`/api/data?page=${page}`);
    const data = await response.json();
    
    yield data;
    
    if (data.lastPage) break;
    page++;
  }
}

for await (const page of fetchPages()) {
  console.log(page.items);
}

Что НЕ является итерируемым

const obj = { a: 1, b: 2, c: 3 };

for (const value of obj) { // ОШИБКА!
  console.log(value);
}

// Правильно: для обычных объектов используй Object.entries, Object.keys, Object.values
for (const [key, value] of Object.entries(obj)) {
  console.log(key, value);
}

for (const key of Object.keys(obj)) {
  console.log(key);
}

for (const value of Object.values(obj)) {
  console.log(value);
}

Резюме

for...of применяется для:

  • Обхода массивов (более современен, чем for)
  • Итерирования по Set, Map, строкам
  • Обхода NodeList и других итерируемых объектов
  • Случаев, когда нужны break и continue (в отличие от forEach)
  • Работы с асинхронными итераторами (for await...of)

Преимущества for...of:

  • Читаемый и понятный синтаксис
  • Поддержка break, continue, return
  • Работает со всеми итерируемыми объектами
  • Потенциально более оптимален, чем forEach

Не используй for...of для:

  • Обычных объектов (используй Object.entries, for...in)
  • Трансформации данных (используй map, filter, reduce)
Когда применяется цикл for…of? | PrepBro