> For the complete documentation index, see [llms.txt](https://strctr.gitbook.io/programming/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://strctr.gitbook.io/programming/01-languages/javascript/01-language/e-controls/e1-iteration/02-iterators.md).

# 02. Iterators

Итераторы являются общим стандартном передачи данных между источником данных и их получателем.

* Источник данных реализует итератор.
* Потребитель данных ожидает итератор для получения данных.

В этом смысле итераторы в ES6 формируют протокол (интерфейс и множество правил его использования).

## Iterable object

Объект является итерируемым, если на нем определен `Symbol.iterator`. При вызове метода `Symbol.iterator` перебираемый объект, реализующий протокол итератора.

Интерфейс итератора:

```javascript
interface Iterable {
    [System.iterator]() : Iterator;
}

interface Iterator {
    next() : IteratorResult;
    return?(value? : any) : IteratorResult;
    throw()
}

interface IteratorResult {
    value: any;
    done: boolean;
}
```

Правила итератора:

* Вызов `Symbol.iterator` должен возвращать новый итератор на каждый свой вызов.
* Итератор должен возвращать данные последовательно.
* Итератор должен возвращать по одному объекту за раз.

## Iterator protocol

По стандарту у объекта итератора должен быть метод `next()`, который при каждом вызове возвращает объект следующей структуры `{ value: any, done: boolean}`

* `value` — очередное значение,
* `done` — равно `false`, если есть ещё значения, и `true` — в конце.

Итерация прекращается когда возвращается объект с `{done: true}`. Это последний шаг итерации. При стандартном алгоритме итерации, значение, возвращаемое на последнем шаге игнорируется.

Привет простого итератора:

```javascript
const iterable = {
  [Symbol.iterator]() {
    let step = 0;
    const iterator = {
      next() {
        if (step <= 2) {
          step++;
        }
        switch (step) {
          case 1:
            return { value: "hello", done: false };
          case 2:
            return { value: "world", done: false };
          default:
            return { value: undefined, done: true };
        }
      }
    };
    return iterator;
  }
};

for (const x of iterable) {
  console.log(x);
}
// Output:
// hello
// world
```

Возможны и бесконечные итераторы. Нет никаких ограничений на `next`, он может возвращать всё новые и новые значения, и это нормально.
