JavaScript Iterators

Learn iterators, the iteration protocol, and generators for controlling how data is consumed.

TL;DR

  1. 01Expose a next method returning value and done properties.
  2. 02Implement Symbol.iterator to make custom objects natively iterable.
  3. 03Use generator functions to construct custom iterables efficiently.

Tips

  1. 01Use generator functions to implement the iteration contract automatically without manual state tracking.
  2. 02Delegate execution to nested iterables using yield* to simplify generator loop declarations.

Warnings

  1. 01Remember that exhausted iterators cannot be reused without obtaining a fresh iterator instance.
  2. 02Convert plain objects using Object.entries() before attempting loop iteration over them.

What Iterators Are

    Iterator definition

    Provides a next method returning value and done flags.

    const arr = [10, 20];
    const it = arr[Symbol.iterator]();
    it.next(); // { value: 10, done: false }
    Iteration state

    Tracks progress dynamically, returning done: true when complete.

    it.next(); // { value: 20, done: false }
    it.next(); // { value: undefined, done: true }
    Underlying support

    Powers loops, spreads, and destructuring operations implicitly.

    const [x, y] = [10, 20]; // uses iterator

Iteration Protocol

    Custom iterables

    Implements Symbol.iterator to make objects work with for-of.

    const obj = {
      data: [1, 2, 3],
      [Symbol.iterator]() {
        let i = 0;
        return {
          next: () => ({
            value: this.data[i],
            done: i++ >= this.data.length
          })
        };
      }
    };
    for (const n of obj) console.log(n);
    Required structures

    Demands the standard iterator method shape to match engine interfaces.

    // Iterator returns: { next() { ... } }

Built-in Iterables

    Standard collections

    Provides native iteration for strings, arrays, sets, and maps.

    for (const char of "Hi!") console.log(char);
    for (const val of new Set([1, 2])) console.log(val);
    Map entries

    Iterates over key-value pairs using array destructuring syntax.

    const map = new Map([['a', 1]]);
    for (const [k, v] of map) console.log(k, v);
    DOM NodeLists

    Supports for-of iteration on elements retrieved from DOM queries.

    const divs = document.querySelectorAll("div");
    for (const div of divs) console.log(div);

Generators

    Generator functions

    Pauses function execution using the yield keyword.

    function* greet() {
      const name = yield "name?";
      yield `Hello, ${name}!`;
    }
    const g = greet();
    g.next().value; // "name?"
    g.next("Ada").value; // "Hello, Ada!"
    Generator delegation

    Delegates execution to nested iterables using the yield* operator.

    function* combine() {
      yield* [1, 2];
      yield* ['a', 'b'];
    }
    console.log([...combine()]); // [1, 2, 'a', 'b']

In Practice

FAQ