The Iterator Protocol
Any object implementing Symbol.iterator() that returns an object with next() method is iterable. This protocol powers for...of, spread, destructuring, and Array.from().
// Custom iterable object:
const counter = {
from: 1,
to: 5,
[Symbol.iterator]() {
let current = this.from;
const last = this.to;
return {
next() {
return current <= last
? { value: current++, done: false }
: { value: undefined, done: true };
}
};
}
};
for (const n of counter) console.log(n); // 1 2 3 4 5
console.log([...counter]); // [1,2,3,4,5]
const [first, ...rest] = counter; // destructuring
// Built-in iterables: String, Array, Map, Set, NodeList
const str = "hello";
console.log([...str]); // ["h","e","l","l","o"]
const map = new Map([["a",1],["b",2]]);
for (const [key, value] of map) {
console.log(key, value);
}
// Infinite iterator:
function naturals() {
let n = 0;
return {
[Symbol.iterator]() { return this; },
next() { return { value: n++, done: false }; }
};
}
function take(iter, n) {
return Array.from({ length: n }, () => iter.next().value);
}
console.log(take(naturals(), 5)); // [0,1,2,3,4]
⚡ Key Takeaways
- Iterable: has [Symbol.iterator]() returning an iterator
- Iterator: has next() returning {value, done}
- Iterables work with for...of, spread, Array.from(), destructuring
- Strings, Arrays, Maps, Sets are built-in iterables
- Generators (next lesson) are the easiest way to create custom iterators
🎯 Practice Exercises
EXERCISE 1
Create a Fibonacci iterable that yields Fibonacci numbers endlessly. Use take() to get the first 15 Fibonacci numbers.