The iterable protocol lets an object control how its elements are delivered. An iterable exposes a function-valued Symbol.iterator; calling it produces an iterator whose next method returns { value, done }. section 9.1.1 section 9.6
JavaScript consumes iterables through for...of, the spread operator, and destructuring assignment. Arrays, Maps, Sets, and strings already implement the protocol, while custom objects can define their own traversal. section 7.5.5 section 9.1.1
Implement an iterable by choosing what its iterator emits:
- Return an existing iterator when the object delegates storage to another iterable, such as a Map or an array. section 7.5.5
- Return a custom iterator whose next method reports each value and eventually sets done to true. section 7.5.5
- Use a generator function for concise sequential emission; its Generator object already implements the iterator protocol. section 9.2.2 section 9.6
Delegating iteration to stored data
A Block can expose its transactions directly by returning this.data[Symbol.iterator](). Consumers can then write for (const transaction of block) and receive each transaction without knowing how the block stores it. section 7.5.5
Making a value pair iterable
A Pair generator can yield its left and right values, allowing const [left, right] = pair and [...pair] to produce the pair’s two elements. This makes custom objects compose with familiar language syntax. section 9.2.2
Listing 7.24 Enumerating a string as a character array
[...'JoJS']; // [ 'J', 'o', 'J', 'S' ] #1
const [first, ...rest] = 'JoJS'; #2
first; // 'J'
rest; // ['o', 'J', 'S' ]
const str = 'JoJS'[Symbol.iterator](); #3
str.next(); // { value: 'J', done: false }
str.next(); // { value: 'o', done: false }
str.next(); // { value: 'J', done: false }
str.next(); // { value: 'S', done: false }
str.next(); // { value: undefined, done: true }
Shows string iteration through spread, destructuring, direct Symbol.iterator calls, and successive next results. section 7.5.5

