JS Iterator Pattern
Traverse a collection sequentially without exposing its internal structure
When to Use
- You need to iterate over a custom data structure (tree, graph, linked list) with
for...of
- You want to provide lazy, on-demand values without generating the entire collection upfront
- Building data pipelines that compose iterables (filter, map, take)
Instructions
- Implement the iterator protocol: an object with a
next() method returning { value, done }.
- Make a collection iterable by adding
[Symbol.iterator]() that returns an iterator.
- Use generator functions (
function*) for the cleanest iterator implementation.
- Use
for...of to consume iterables.
class Range {
constructor(start, end) {
this.start = start;
this.end = end;
}
[Symbol.iterator]() {
let current = this.start;
const end = this.end;
return {
next() {
return current <= end
? { value: current++, done: false }
: { value: undefined, done: true };
},
};
}
}
for (const n of new Range(1, 3)) {
console.log(n); // 1, 2, 3
}
- Generator shorthand:
*[Symbol.iterator]() { for (let i = this.start; i <= this.end; i++) yield i; }.
Details
JavaScript has a built-in iteration protocol. Any object with a [Symbol.iterator]() method is iterable and works with for...of, spread (...), destructuring, Array.from(), and Promise.all(). Generators (function*) are the simplest way to create custom iterators.
Trade-offs:
- Custom iterators add complexity — only worthwhile for non-trivial data structures
- Infinite iterators (no
done: true) will hang for...of loops unless guarded
- Generator objects are single-use — once exhausted, they cannot be reset
When NOT to use:
- For arrays and built-in collections — they are already iterable
- When you need random access — iterators are sequential by design
Source
https://patterns.dev/javascript/iterator-pattern
Process
- Read the instructions and examples in this document.
- Apply the patterns to your implementation, adapting to your specific context.
- Verify your implementation against the details and edge cases listed above.
Harness Integration
- Type: knowledge — this skill is a reference document, not a procedural workflow.
- No tools or state — consumed as context by other skills and agents.
Success Criteria
- The patterns described in this document are applied correctly in the implementation.
- Edge cases and anti-patterns listed in this document are avoided.
1---2name: js-iterator-pattern3description: JS Iterator Pattern4---5# JS Iterator Pattern67> Traverse a collection sequentially without exposing its internal structure89## When to Use1011- You need to iterate over a custom data structure (tree, graph, linked list) with `for...of`12- You want to provide lazy, on-demand values without generating the entire collection upfront13- Building data pipelines that compose iterables (filter, map, take)1415## Instructions16171. Implement the iterator protocol: an object with a `next()` method returning `{ value, done }`.182. Make a collection iterable by adding `[Symbol.iterator]()` that returns an iterator.193. Use generator functions (`function*`) for the cleanest iterator implementation.204. Use `for...of` to consume iterables.2122```javascript23class Range {24 constructor(start, end) {25 this.start = start;26 this.end = end;27 }2829 [Symbol.iterator]() {30 let current = this.start;31 const end = this.end;32 return {33 next() {34 return current <= end35 ? { value: current++, done: false }36 : { value: undefined, done: true };37 },38 };39 }40}4142for (const n of new Range(1, 3)) {43 console.log(n); // 1, 2, 344}45```46475. Generator shorthand: `*[Symbol.iterator]() { for (let i = this.start; i <= this.end; i++) yield i; }`.4849## Details5051JavaScript has a built-in iteration protocol. Any object with a `[Symbol.iterator]()` method is iterable and works with `for...of`, spread (`...`), destructuring, `Array.from()`, and `Promise.all()`. Generators (`function*`) are the simplest way to create custom iterators.5253**Trade-offs:**5455- Custom iterators add complexity — only worthwhile for non-trivial data structures56- Infinite iterators (no `done: true`) will hang `for...of` loops unless guarded57- Generator objects are single-use — once exhausted, they cannot be reset5859**When NOT to use:**6061- For arrays and built-in collections — they are already iterable62- When you need random access — iterators are sequential by design6364## Source6566https://patterns.dev/javascript/iterator-pattern6768## Process69701. Read the instructions and examples in this document.712. Apply the patterns to your implementation, adapting to your specific context.723. Verify your implementation against the details and edge cases listed above.7374## Harness Integration7576- **Type:** knowledge — this skill is a reference document, not a procedural workflow.77- **No tools or state** — consumed as context by other skills and agents.7879## Success Criteria8081- The patterns described in this document are applied correctly in the implementation.82- Edge cases and anti-patterns listed in this document are avoided.