Behavioral pattern
Iterator
One uniform way to walk through a collection's elements, one at a time, without the caller ever knowing whether it's stored as an array, a tree, or a linked list.
✗ The problem
Every collection is traversed its own way
An array walks by index. A tree walks by recursion. A linked list walks by chasing pointers. Client code has to know which — and repeat that knowledge everywhere it loops.
function printAll(coll) {
if (Array.isArray(coll)) {
for (let i = 0; i < coll.length; i++)
show(coll[i]); // index loop
} else if (coll.root) {
walkTree(coll.root); // recursion
} else if (coll.head) {
let n = coll.head;
while (n) { show(n.val); n = n.next; } // pointer chase
}
}
The traversal logic leaks the collection's internals everywhere — swap the
array for a tree and every caller like this one breaks.
✓ The pattern
→
→
Expose one uniform contract: next()
The collection hands out an iterator with a uniform contract —
next() / hasNext(), or JS's built-in [Symbol.iterator]. The
caller loops the same way no matter what's inside.
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let i = this.start, end = this.end;
return {
next: () => i <= end
? { value: i++, done: false }
: { value: undefined, done: true }
};
}
}
Client
Iterator
next() / hasNext()
Collection
hidden internals
✓ See it live
Same loop, any collection
A Range(1, 6) hands out an iterator. Click Next to pull
values one at a time — the client never touches start / end directly.
for (const n of range) {
show(n); // pulls one value at a time
}
1
2
3
4
5
6
cursor: not started
✓ Takeaway
Sequential access without exposing internals
- Sequential access to elements without exposing how they're stored.
- Multiple independent traversals — each iterator keeps its own cursor.
- You use it constantly: JS
for…of, generators, the spread operator, Java/Python iterators. - Careful: don't mutate a collection while an iterator over it is still in flight.
🎯 Principle applied: Iterator separates traversal from
the collection (SRP) and hides internal structure (encapsulation), so storage can
change without breaking callers.
Back to all topics →