Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Создание итератора без генератора
Итератор - это объект, который последовательно возвращает значения через метод next(). В JavaScript можно создать итератор без использования function* (генератора), реализовав протокол итератора.
Протокол итератора
Объект должен иметь метод Symbol.iterator, который возвращает объект с методом next(). Метод next() должен возвращать объект с полями value и done:
class CounterIterator {
constructor(max) {
this.max = max;
this.current = 0;
}
[Symbol.iterator]() {
return this; // Сам объект является итератором
}
next() {
if (this.current < this.max) {
return {
value: this.current++,
done: false
};
}
return { done: true };
}
}
const counter = new CounterIterator(3);
for (const num of counter) {
console.log(num); // 0, 1, 2
}
Итератор в отдельном классе
Можно отделить коллекцию от логики итерации:
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
return new RangeIterator(this.start, this.end);
}
}
class RangeIterator {
constructor(start, end) {
this.current = start;
this.end = end;
}
next() {
if (this.current < this.end) {
return { value: this.current++, done: false };
}
return { done: true };
}
}
const range = new Range(1, 5);
console.log([...range]); // [1, 2, 3, 4]
for (const num of range) {
console.log(num);
}
Итератор с состоянием
Для более сложных сценариев, например обхода дерева:
class TreeNode {
constructor(value, left = null, right = null) {
this.value = value;
this.left = left;
this.right = right;
}
}
class TreeIterator {
constructor(root) {
this.stack = root ? [root] : [];
}
[Symbol.iterator]() {
return this;
}
next() {
if (this.stack.length === 0) {
return { done: true };
}
const node = this.stack.pop();
if (node.right) this.stack.push(node.right);
if (node.left) this.stack.push(node.left);
return { value: node.value, done: false };
}
}
const tree = new TreeNode(1,
new TreeNode(2),
new TreeNode(3)
);
for (const val of new TreeIterator(tree)) {
console.log(val); // 1, 2, 3 (или другой порядок в зависимости от реализации)
}
Фильтрующий итератор
Пример итератора, который фильтрует элементы во время итерации:
class FilterIterator {
constructor(items, predicate) {
this.items = items;
this.predicate = predicate;
this.index = 0;
}
[Symbol.iterator]() {
return this;
}
next() {
while (this.index < this.items.length) {
const item = this.items[this.index++];
if (this.predicate(item)) {
return { value: item, done: false };
}
}
return { done: true };
}
}
const numbers = [1, 2, 3, 4, 5, 6];
const evenIterator = new FilterIterator(numbers, n => n % 2 === 0);
for (const num of evenIterator) {
console.log(num); // 2, 4, 6
}
Отличие от генератора
Генератор function* более лаконичен, но кастомный итератор дает полный контроль и лучше работает с классами и сложной логикой управления состоянием.