JS Intermediate

Итерируемые объекты

Понять протокол итерации: что такое iterable, iterator, next(), и как создавать свои итерируемые объекты через Symbol.iterator.

Средний (Intermediate)

Кратко

for...of работает не только с массивами — с любым итерируемым объектом. Iterable — объект с методом Symbol.iterator, который возвращает iterator. Iterator имеет метод next(), возвращающий { value, done }.


Подробно

Что такое iterable?

Iterable — объект, который можно перебрать через for...of. Встроенные iterables: Array, String, Map, Set, NodeList.

Что делает for...of? for (const item of iterable) { ... }

Это эквивалентно: const iterator = iterable[Symbol.iterator](); let result = iterator.next(); while (!result.done) { const item = result.value; // ... тело цикла result = iterator.next(); }

Symbol.iterator: Объект — iterable, если у него есть метод [Symbol.iterator], который возвращает iterator.

Iterator: Объект с методом next(), который возвращает { value, done }.

class Range { constructor(start, end) { this.start = start; this.end = end; }

[Symbol.iterator]() { let current = this.start; const end = this.end;

return { next() { if (current <= end) { return { value: current++, done: false }; } return { value: undefined, done: true }; } }; } }

for (const num of new Range(1, 5)) { console.log(num); // 1, 2, 3, 4, 5 }


Ментальная модель

Iterable — как книга. Iterator — как закладка. Вы открываете книгу (Symbol.iterator) и получаете закладку (iterator). Каждый раз, когда вы читаете страницу (next()), закладка двигается вперёд. Когда книга закончится (done: true) — вы останавливаетесь.


Примеры

**Самый простой:**

javascript
const arr = [1, 2, 3];
const str = 'abc';
const set = new Set([1, 2, 3]);
const map = new Map([['a', 1], ['b', 2]]);

// Все — iterable:
for (const item of arr)  console.log(item);
for (const char of str) console.log(char);
for (const item of set) console.log(item);
for (const [key, val] of map) console.log(key, val);

for...of работает с любым iterable.

**Простой:**

javascript
// Ручной вызов iterator:
const arr = [10, 20, 30];
const iterator = arr[Symbol.iterator]();

console.log(iterator.next()); // { value: 10, done: false }
console.log(iterator.next()); // { value: 20, done: false }
console.log(iterator.next()); // { value: 30, done: false }
console.log(iterator.next()); // { value: undefined, done: true }

Каждый вызов next() возвращает следующее значение.

**Реальный пример:**

javascript
class Fibonacci {
  constructor(limit) {
    this.limit = limit;
  }

  [Symbol.iterator]() {
    let a = 0, b = 1, count = 0;
    const limit = this.limit;

    return {
      next() {
        if (count >= limit) return { value: undefined, done: true };
        const value = a;
        [a, b] = [b, a + b];
        count++;
        return { value, done: false };
      }
    };
  }
}

for (const num of new Fibonacci(8)) {
  console.log(num); // 0, 1, 1, 2, 3, 5, 8, 13
}

Кастомный iterable: бесконечная последовательность Фибоначчи с лимитом.


Частые ошибки

**Неправильно:** Путать iterable и iterator

**Почему:** Iterable — объект с Symbol.iterator. Iterator — объект с next(). Разные роли.

**Правильно:** Iterable возвращает iterator. Iterator возвращает значения.

**Неправильно:** Думать, что for...of работает с объектами {}

**Почему:** Обычные объекты НЕ iterable. Только Array, String, Map, Set, NodeList и т.д.

**Правильно:** Для объектов используйте Object.keys/values/entries + for...of.

**Неправильно:** Забывать возвращать { value, done } из next()

**Почему:** next() должен возвращать объект с свойствами value и done.

**Правильно:** return { value: ..., done: true/false }.


Важно запомнить

  • Iterable имеет Symbol.iterator, возвращающий iterator
  • Iterator имеет next(), возвращающий { value, done }
  • for...of = iterable[Symbol.iterator]() + next() цикл
  • Обычные {} — НЕ iterable
  • Array, String, Map, Set — встроенные iterables

Связь

Назад: Вы знаете Map и Set (JI18) — они тоже итерируемые! Теперь вы знаете, почему.

Вперёд: Вы завершили JS Intermediate! Дальше — JS Async: промисы и async/await.

Материалы курса JS Intermediate — PROlab Academy.