Behavioral · DWG NO. 019

Iterator

Give a collection a uniform way to be walked through, without exposing how it stores its elements internally.

TypeBehavioral
ScopeSingle collection
ComplexityLow
Common inCustom collections, pagination, tree traversal

Client code reaching into a collection's internals to loop over it

If callers loop over a custom collection using `collection.items[i]`, the collection can never change its internal storage (say, from an array to a linked list) without breaking every caller that assumed array indexing.

A cursor object, separate from the collection

The collection exposes a method that returns an iterator — an object with `next()` that tracks position on its own. Client code calls `next()` repeatedly and never touches the collection's internal structure.

Collection[Symbol.iterator]Iterator.next()Client

A custom collection with its own iterator

Because `Range` implements the iterable protocol, it works directly with `for...of` — the internal storage stays private.

range-iterator.js
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 { value: undefined, done: true };
      },
    };
  }
}

for (const n of new Range(1, 5)) {
  console.log(n); // 1 2 3 4
}

console.log([...new Range(0, 3)]); // [0, 1, 2]

Trade-offs