Что такое Symbol.iterator и зачем он нужен
Symbol.iterator
— это специальный символ, используемый в JavaScript для создания итерируемых объектов, то есть таких, которые можно перебирать с помощью for...of
, оператора расширения (...
), или использовать в других случаях, где требуется итерируемый интерфейс.
Итерируемые объекты
Объекты, у которых определён метод с ключом Symbol.iterator
, считаются итерируемыми. Это:
- массивы
[]
- строки
"hello"
- множества
Set
- карты
Map
arguments
- и другие встроенные коллекции
Пример:
const arr = [1, 2, 3];
for (const value of arr) {
console.log(value); // 1, 2, 3
}
Здесь arr[Symbol.iterator]
автоматически вызывается в for...of
.
Как работает Symbol.iterator
Метод Symbol.iterator
должен возвращать объект итератора, у которого есть метод next()
.
Этот метод возвращает объект с двумя свойствами:
value
— текущее значениеdone
— булево, указывает завершен ли перебор
Пример собственного итератора
const customIterable = {
data: [10, 20, 30],
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.data.length) {
return { value: this.data[index++], done: false };
} else {
return { done: true };
}
}
};
}
};
for (const num of customIterable) {
console.log(num); // 10, 20, 30
}
Почему нельзя итерировать обычный объект?
const obj = { a: 1, b: 2 };
for (const key of obj) {
// TypeError: obj is not iterable
}
Объекты по умолчанию не являются итерируемыми, потому что у них нет метода [Symbol.iterator]
.
Чтобы сделать объект итерируемым, нужно явно определить этот метод.
Где используется Symbol.iterator
for...of
spread (...)
Array.from()
Promise.all
Set
Map
деструктуризация: [...something]
Вывод
Symbol.iterator
— ключ к итерируемости.- Любой объект, реализующий
[Symbol.iterator]
, можно использовать вfor...of
. - Вы можете создавать свои структуры данных, поддерживающие итерацию по вашему сценарию.
Факт:
Именно Symbol.iterator
делает возможной работу таких конструкций как for...of
, ...spread
, и даже yield*
в генераторах.