What are iterators and the iterable protocol?
These protocols define how objects can be looped with for...of and spread.
Iterable — an object with a Symbol.iterator method that returns an iterator.
Iterator — an object with a next() method returning { value, done }.
Built-ins — arrays, strings, Maps, and Sets are all iterable.
DIY: implement Symbol.iterator on your own objects to make them work with for...of and spread.
// Custom iterable
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
if (current <= end) {
return { value: current++, done: false };
}
return { done: true };
}
};
}
}
const range = new Range(1, 5);
for (const n of range) console.log(n); // 1, 2, 3, 4, 5
console.log([...range]); // [1, 2, 3, 4, 5]
const [first, second] = range; // 1, 2
// Manual iteration
const iter = range[Symbol.iterator]();
console.log(iter.next()); // { value: 1, done: false }
console.log(iter.next()); // { value: 2, done: false }
// Making any object iterable
const users = {
data: ['Alice', 'Bob', 'Charlie'],
[Symbol.iterator]() {
let index = 0;
return {
next: () => index < this.data.length
? { value: this.data[index++], done: false }
: { done: true }
};
}
};
for (const user of users) console.log(user); // Alice, Bob, CharlieRange implements [Symbol.iterator] returning an iterator with next(). This enables for...of, spread, and destructuring.
Each call to next() increments current until it exceeds end. The users object example shows making any object iterable by adding the Symbol.iterator protocol.
Implement a custom iterable with [Symbol.iterator] and next() — this is a common interview question. Show that it works with for...of, spread, and destructuring.
Know which built-ins are iterable (Array, String, Map, Set) and which are not (plain objects).