Перебираемые (или итерируемые) объекты – это концепция, которая позволяет использовать любой объект в цикле for..of
.
Объект является итератором, если он умеет обращаться к элементам коллекции по одному за раз, при этом отслеживая своё текущее положение внутри этой последовательности.
В JavaScript итератор - это объект, который предоставляет метод next(), возвращающий следующий элемент последовательности. Этот метод возвращает объект с двумя свойствами: done
и value
.
done
- флаг, указывающий, что текущий элемент является последнимvalue
- значение текущей итерации. Значение последнего э
function makeIterator(array){
var nextIndex = 0;
return {
next: function(){
return nextIndex < array.length ?
{value: array[nextIndex++], done: false} :
{done: true};
}
}
}
Можно сделать объект итерируемым, присвоив Symbol.iterator
функцию, которая возвращает итератор:
let range = {
from: 1,
to: 5
}
// 1. вызов for..of сначала вызывает эту функцию
range[Symbol.iterator] = () => {
// ...она возвращает объект итератора:
// 2. Далее, for..of работает только с этим итератором, запрашивая у него новые значения
return {
current: this.from,
last: this.to,
// 3. next() вызывается на каждой итерации цикла for..of
next() {
// 4. он должен вернуть значение в виде объекта {done:.., value :...}
if (this.current <= this.last) {
return { done: false, value: this.current++ };
} else {
return { done: true };
}
}
}
}
Есть два официальных термина, которые очень похожи, но в то же время сильно различаются. Поэтому убедитесь, что вы как следует поняли их, чтобы избежать путаницы.
- Итерируемые объекты – это объекты, которые реализуют метод
Symbol.iterator
, как было описано выше. - Псевдомассивы – это объекты, у которых есть индексы и свойство
length
, то есть, они выглядят как массивы.
- Технически итерируемые объекты должны иметь метод
Symbol.iterator
.- Результат вызова
obj[Symbol.iterator]
называется итератором. Он управляет процессом итерации. - Итератор должен иметь метод
next()
, который возвращает объект{done: Boolean, value: any}
, гдеdone:true
сигнализирует об окончании процесса итерации, в противном случаеvalue
– следующее значение.
- Результат вызова
- Метод
Symbol.iterator
автоматически вызывается цикломfor..of
, но можно вызвать его и напрямую. - Встроенные итерируемые объекты, такие как строки или массивы, также реализуют метод
Symbol.iterator
. - Строковый итератор знает про суррогатные пары.