Hint
[Symbol.iterator] is called fresh each time the object is iterated โ making the iterable reusable. The returned iterator is the stateful part.
const range = {
start: 1,
end: 4,
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
return current <= end
? { value: current++, done: false }
: { value: undefined, done: true };
}
};
}
};
console.log([...range]);
for (const n of range) process.stdout.write(n + ' ');[1, 2, 3, 4] 1 2 3 4
Explanation: The range object has [Symbol.iterator] so it's iterable. Spread and for...of both call it. Each call creates a fresh iterator from start, so the range is reusable.
Key Insight: [Symbol.iterator] is called fresh each time the object is iterated โ making the iterable reusable. The returned iterator is the stateful part.