Docs

README

17.4 Iterators and Iterables

Overview

Iterators and iterables are protocols that allow objects to define their iteration behavior. They enable the use of for...of loops, spread operator, and other iteration constructs.

The Protocols

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                   Iterator and Iterable Protocols                       │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                         │
│  ITERABLE PROTOCOL                                                      │
│  ─────────────────                                                      │
│  An object is iterable if it has a [Symbol.iterator] method             │
│  that returns an iterator.                                              │
│                                                                         │
│  const iterable = {                                                     │
│      [Symbol.iterator]() {                                              │
│          return iterator;  // Returns an iterator object                │
│      }                                                                  │
│  };                                                                     │
│                                                                         │
│  ITERATOR PROTOCOL                                                      │
│  ─────────────────                                                      │
│  An object is an iterator if it has a next() method that returns        │
│  { value: any, done: boolean }                                          │
│                                                                         │
│  const iterator = {                                                     │
│      next() {                                                           │
│          return { value: 1, done: false };                              │
│          // or { done: true } when finished                             │
│      }                                                                  │
│  };                                                                     │
│                                                                         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Built-in Iterables

TypeDescription
StringIterates over characters
ArrayIterates over elements
MapIterates over [key, value] pairs
SetIterates over values
TypedArrayIterates over elements
argumentsIterates over arguments
NodeListIterates over nodes

Custom Iterator Example

const range = {
  start: 1,
  end: 5,

  [Symbol.iterator]() {
    let current = this.start;
    const last = this.end;

    return {
      next() {
        if (current <= last) {
          return { value: current++, done: false };
        }
        return { done: true };
      },
    };
  },
};

for (const num of range) {
  console.log(num); // 1, 2, 3, 4, 5
}

Iterator Methods

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      Iterator Methods                                   │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                         │
│  next()    - Required. Returns { value, done }                          │
│  return()  - Optional. Called when iteration stops early (break)        │
│  throw()   - Optional. Called to signal an error                        │
│                                                                         │
│  const iterator = {                                                     │
│      next() {                                                           │
│          return { value: 1, done: false };                              │
│      },                                                                 │
│      return() {                                                         │
│          console.log('Cleanup');                                        │
│          return { done: true };                                         │
│      }                                                                  │
│  };                                                                     │
│                                                                         │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Consuming Iterables

Constructs that use iterables:

  • •for...of loop
  • •Spread operator ...
  • •Array.from()
  • •Destructuring
  • •Map(), Set(), WeakMap(), WeakSet()
  • •Promise.all(), Promise.race()
  • •yield*

Infinite Iterators

const infiniteCounter = {
  [Symbol.iterator]() {
    let n = 0;
    return {
      next() {
        return { value: n++, done: false };
      },
    };
  },
};

// Be careful - use with break or take first N
for (const num of infiniteCounter) {
  if (num > 5) break;
  console.log(num);
}

Summary

  • •Iterables have [Symbol.iterator]() method
  • •Iterators have next() method
  • •next() returns { value, done }
  • •Many constructs consume iterables
  • •Custom iteration enables powerful patterns
README - JavaScript Tutorial | DeepML