Вопрос проверяет понимание различий между интерфейсами Iterable и Iterator в JavaScript, что необходимо для корректной работы с циклами for...of и создания пользовательских итерируемых объектов.
В JavaScript протокол итерации позволяет объектам определять или настраивать своё поведение при итерации, например, в цикле for...of. Ключевыми компонентами этого протокола являются интерфейсы Iterable и Iterator.
Объект является итерируемым, если он реализует метод с ключом Symbol.iterator. Этот метод должен возвращать объект, соответствующий интерфейсу Iterator. Стандартные встроенные типы, такие как Array, String, Map, Set, являются итерируемыми по умолчанию.
const arr = [1, 2, 3];
// Получаем итератор из итерируемого объекта
const iterator = arr[Symbol.iterator]();
console.log(iterator.next()); // { value: 1, done: false }Итератор — это объект, который реализует метод next(). При каждом вызове next() возвращается объект с двумя свойствами: value (текущее значение) и done (логический флаг, указывающий, завершена ли итерация). Итератор управляет состоянием итерации (например, текущей позицией).
function createSimpleIterator(max) {
let count = 0;
return {
next() {
if (count < max) {
return { value: count++, done: false };
}
return { value: undefined, done: true };
}
};
}
const myIterator = createSimpleIterator(3);
console.log(myIterator.next()); // { value: 0, done: false }Когда цикл for...of запускается для итерируемого объекта, он сначала вызывает метод Symbol.iterator, чтобы получить итератор, а затем повторно вызывает next() на этом итераторе, пока done не станет true. Это разделение позволяет иметь несколько независимых итераторов для одного и того же итерируемого объекта.
...) и деструктуризацией, которые также работают с итерируемыми объектами.// Пример пользовательского Iterable
const range = {
from: 1,
to: 3,
[Symbol.iterator]() {
let current = this.from;
let last = this.to;
return {
next() {
if (current <= last) {
return { value: current++, done: false };
}
return { done: true };
}
};
}
};
for (let num of range) {
console.log(num); // 1, 2, 3
}Вывод: Используйте Iterable, когда нужно определить объект, который можно перебирать (например, в for...of). Iterator — это низкоуровневый механизм для управления процессом итерации; он полезен, когда требуется тонкий контроль над обходом данных или реализация ленивых вычислений.