All topics
ES6+advanced

Iterators and the Iterable Protocol

The formal protocol that makes an object usable with for...of, spread syntax, and destructuring, and how to implement it on custom objects.

JavaScript's for...of loop, spread syntax, and destructuring all rely on a shared, formally specified iterable protocol, rather than being hardcoded specifically to work with arrays. Understanding this protocol lets you make custom data structures behave like native collections, a strong signal of deep language knowledge.

The iterable protocol is like a standardized vending machine interface: any manufacturer's machine implementing the same coin slot and dispensing mechanism can be used by the exact same universal vending customer without needing to know anything special about which brand it is.

Key Concepts

1
An object is iterable if it implements a method at the well-known key Symbol.iterator, which must return an iterator — an object with a next() method returning {value, done} on each call. for...of, spread, and destructuring all work by calling obj[Symbol.iterator]() to get an iterator, then repeatedly calling .next() until done is true.
2
Many built-in types already implement this: arrays, strings, Map, Set, and arguments are all natively iterable, whereas a plain object is not iterable by default unless you give it a Symbol.iterator method yourself.
3
Implementing the protocol manually means writing a [Symbol.iterator]() method returning a conforming next(), though in practice generator functions are almost always used instead, since a generator's return value automatically satisfies the entire protocol.