ReviseAlgo Logo

Design Patterns

Iterator Pattern

Master the Iterator Pattern in JavaScript. Learn to implement custom iterators, conform to the iterable protocol, and yield values using generators.

Last Updated: July 15, 2026 10 min read

1. Introduction

The Iterator Pattern is a design pattern that provides a way to access the elements of a collection sequentially without exposing its underlying structure. In JavaScript, this is standardized via the Iterable Protocol and Generators.

2. Why It Matters

Different data structures (like arrays, maps, sets, or binary trees) store elements in different ways. The Iterator pattern provides a standardized way to traverse these collections (like using for...of loops or the spread operator) regardless of how the elements are stored.

3. Real-World Analogy

Think of a Supermarket Checkout Scanner:

  • Direct Access (Rummaging): A clerk empties a shopper's cart onto the counter, opening boxes to check items. This requires knowing how every item is packaged.
  • Iterator (Standard conveyor belt): The shopper places items on a conveyor belt one by one. The cashier slides each item past a laser scanner. Symmetrically, the scanner only reads the barcode (calls next()) to get the item and check if more items remain (checks done), without needing to know what is inside the boxes.

4. The Iterable Protocol

For an object to be iterable in JavaScript, it must implement the Symbol.iterator method. This method returns an iterator object containing a next() method, which returns an object with value and done properties:

5. Generators (Simpler Iterators)

Writing custom iterator objects with state counters can be tedious. Generator Functions (function*) simplify this by automatically conforming to the iterable protocol using the yield keyword:

6. Practical Example

This script demonstrates implementing a custom collection class that implements the iterable protocol:

7. Common Mistakes

  • Trying to loop over non-iterable objects using for...of: Regular JavaScript objects (e.g. {}) are not iterable by default. Attempting to loop over them using a for...of loop throws a TypeError. Use Object.keys() or implement the Symbol.iterator method to make them iterable.

8. Quick Quiz

Q1: Which method properties must the object returned by Symbol.iterator implement to conform to the iterator protocol?

A) yield()

B) next() returning { value, done }

Answer: B — The iterator object must implement a next() method that returns { value, done } properties sequentially.

9. Scenario-Based Challenge

The Custom LinkedList Traverser:

An application stores items inside a linked list: { value: 1, next: { value: 2, next: null } }. Write a custom iterator using generator functions to traverse this linked list cleanly using for...of loops.

10. Debugging Exercise

Explain why this custom iterator throws a TypeError during loop execution, and how to fix it:

const myCollection = {
  items: [10, 20],
  // Bug: named the iterator method Symbol.iterator string key?
  "Symbol.iterator"() {
    let index = 0;
    return {
      next: () => ({ value: this.items[index++], done: index > this.items.length })
    };
  }
};

for (const x of myCollection) { // TypeError: myCollection is not iterable! Why? console.log(x); }

View Solution

Diagnosis: The method is declared using the literal string key "Symbol.iterator" instead of the evaluated Well-Known Symbol [Symbol.iterator], preventing the engine from identifying it as iterable.

Fix: Wrap the Symbol reference in square brackets to evaluate it as a computed property key:

const myCollection = {
  items: [10, 20],
  [Symbol.iterator]() { // Computed symbol property key
    let index = 0;
    return {
      next: () => {
        return index < this.items.length
          ? { value: this.items[index++], done: false }
          : { done: true };
      }
    };
  }
};

11. Interview Questions

🟢 Q1: Explain how the Iterable and Iterator protocols work in JavaScript.

Answer:
Iterable Protocol: Allows objects to define their iteration behavior. The object must implement a method with the key [Symbol.iterator] that returns an iterator object.
Iterator Protocol: Defines a standard way to produce values. The returned iterator object must implement a next() method that returns an object containing value (the current element) and done (a boolean indicating whether iteration is complete) properties.

12. Production Considerations

  • Generators over Iterators: Prefer using generator functions (function*) to implement custom iterators. Generators manage state counters and iteration flags automatically under the hood, reducing boilerplate and preventing common bugs.