Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як працюють ітератори й протокол Symbol.iterator?

Ітератор - об'єкт з методом next(), який щоразу повертає { value, done }. Ітерований об'єкт має метод [Symbol.iterator](), що повертає ітератор.

Саме на цьому протоколі працюють for...of, spread ([...x]), деструктуризація, Array.from, Promise.all, конструктори Map і Set. Масиви, рядки, Map, Set, NodeList - ітеровані з коробки; звичайні об'єкти - ні.

Власний ітерований об'єкт найпростіше зробити генератором:

class Range {
  constructor(from, to) {
    this.from = from;
    this.to = to;
  }

  *[Symbol.iterator]() {
    for (let i = this.from; i <= this.to; i++) {
      yield i;
    }
  }
}

[...new Range(1, 5)];          // [1, 2, 3, 4, 5]
for (const n of new Range(1, 3)) console.log(n);

Навіщо це на практиці:

  • Ліниві послідовності: значення обчислюються лише тоді, коли їх просять. Можна описати навіть нескінченну послідовність і взяти з неї 10 елементів.
  • Однаковий інтерфейс для власних колекцій - їх можна передавати скрізь, де очікується ітероване.
  • Асинхронні ітератори (Symbol.asyncIterator, for await...of) - для потоків даних: сторінки API, рядки великого файлу, потік відповіді fetch.

Нові «ітераторні хелпери» (Iterator.prototype.map, filter, take, drop) дозволяють працювати з ітераторами ліниво, не перетворюючи їх на масив. Вони вже є в сучасних браузерах і Node.js 22+.

Докладніше в документації: Ітератори й генератори

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання