В JavaScript итератор – это объект, который предоставляет последовательный доступ к элементам коллекции, такой как массив или объект. Он позволяет перебирать элементы коллекции по одному и выполнять определенные операции над ними без необходимости знания внутренней структуры этой коллекции. Итераторы широко используются в JavaScript, особенно в циклах for...of
, spread операторах, и методах массива, таких как map()
, filter()
, и reduce()
.
Для создания итератора в JavaScript можно использовать методы объекта Symbol.iterator
. Этот метод должен вернуть объект, который соответствует интерфейсу итератора. Интерфейс итератора включает в себя метод next()
, который возвращает объект со свойствами value
и done
. value представляет текущий элемент в последовательности, а done
указывает, завершен ли перебор коллекции.
Пример создания итератора для массива:
const myArray = [1, 2, 3];
const iterator = myArray[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // { value: 2, done: false }
console.log(iterator.next()); // { value: 3, done: false }
console.log(iterator.next()); // { value: undefined, done: true }
В этом примере myArray[Symbol.iterator]()
возвращает объект-итератор для массива myArray
. Последовательные вызовы метода next()
возвращают каждый элемент массива в порядке их следования. После последнего элемента метод next()
возвращает объект с done: true
.
Итераторы можно также создавать для собственных объектов. Для этого нужно определить метод Symbol.iterator
в прототипе объекта.
Вот пример:
const myObject = {
data: ['apple', 'banana', 'orange'],
[Symbol.iterator]: function() {
let index = 0;
return {
next: () => {
return index < this.data.length ?
{ value: this.data[index++], done: false } :
{ done: true };
}
};
}
};
const iterator = myObject[Symbol.iterator]();
console.log(iterator.next()); // { value: 'apple', done: false }
console.log(iterator.next()); // { value: 'banana', done: false }
console.log(iterator.next()); // { value: 'orange', done: false }
console.log(iterator.next()); // { done: true }
Это создает объект myObject
, содержащий массив данных и метод Symbol.iterator
, который возвращает итератор для перебора элементов этого массива.
Давайте рассмотрим еще несколько примеров использования итераторов в JavaScript.
for...of
Цикл for...of
предоставляет удобный способ перебора элементов коллекции с использованием итератора.
Вот пример:
const myArray = ['apple', 'banana', 'orange'];
for (const item of myArray) {
console.log(item);
}
// apple
// banana
// orange
Вы также можете создавать собственные итераторы для пользовательских типов данных.
Вот пример с пользовательским классом Range
, представляющим диапазон чисел:
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
*[Symbol.iterator]() {
for (let i = this.start; i <= this.end; i++) {
yield i;
}
}
}
const range = new Range(1, 5);
for (const num of range) {
console.log(num);
}
// 1
// 2
// 3
// 4
// 5
Map
и Set
Объекты Map
и Set
также имеют свои итераторы:
const myMap = new Map([
['a', 1],
['b', 2],
['c', 3]
]);
for (const [key, value] of myMap) {
console.log(`${key} => ${value}`);
}
// a => 1
// b => 2
// c => 3
const mySet = new Set([1, 2, 3, 4, 5]);
for (const item of mySet) {
console.log(item);
}
// 1
// 2
// 3
// 4
// 5