01. Iterable
В JavaScript добавлена новая концепция “итерируемых” (iterable) объектов:
Итерируемый объект (Iterable) - это объект или структура данных, чьи элементы должны быть доступны для последовательного перебора. Сама структура данных не обязательно должна быть линейной, но во время итерации элементы из неё извлекаются в последовательном порядке. Итерируемый объект содержит метод, доступный по символу
Symbol.iterator
. Этот метод является фабрикой для объектов-итераторов.Итератор (Iterator) - объект, реализующий специальный протокол, для обхода элементов в структуре данных. Итераторы используются в тех местах, где нужно передать последовательность данных дальше по назначению -
for-of
,spread
.
Следующие объекты являются итерируемыми:
arguments
Array
String
Set
Map
DOM структуры
Пользовательские объекты, имеющие символ-итератор.
В следующих операциях используется итератор:
Деструкция на основе паттерна массива
for-of
циклArray.from
Spread (
...
)Constructors of Maps and Sets
Promise.all()
,Promise.race()
yield*
На основе итераторов работает множество языковых конструкций, добавленных в ES6:
// Array destruction
const [a,b] = new Set(['a', 'b', 'c']);
// for-of loop
for (const x of ['a', 'b', 'c']) {
console.log(x);
}
// Array.from
const arr = Array.from(new Set(['a', 'b', 'c']));
// spread
const arr = [...new Set(['a', 'b', 'c'])];
// Конструкторы `Set` и `Map`
const map = new Map([[false, 'no'], [true, 'yes']]);
const set = new Set(['a', 'b', 'c']);
// Constructors of Sets and Maps receive iterables:
new Set("123").has("2") // true
new WeakSet(function*() {
yield {};
yield myObj;
yield {};
}()).has(myObj); // true
// Promice.all and Promice.race
Promise.all(iterableOverPromises).then(···);
Promise.race(iterableOverPromises).then(···);
// yield*
yield* anIterable;
Особенности итератора:
Является ли объект итерируемым зависит от наличия на нем метода с ключом
Symbol.iterator
, который возвращает валидный итератор.Обычные объекты не являются итерируемыми.
В отличие от массивов, “перебираемые” объекты могут не иметь “длины”
length
.Возможны и бесконечные итераторы. Нет никаких ограничений на
next
, он может возвращать всё новые и новые значения, и это нормально.Оператор
spread
автоматически превращает итерируемый объект в массив:Math.max(...range);
Если сам объект реализует протокол итератора, тогда и вызов функции-итератора должен просто возвращать
this
.Является ли итератор закрываемым?
Генераторы являются закрываемыми по умолчанию.
Не все итераторы сами являются итерируемыми. То есть не на всех итераторах определен
Symbol.iterator
возвращающийthis
.
Last updated
Was this helpful?