Start · Sprachen · JavaScript · Referenz · Iterator

Iterator

Klasse

Ein <code>Iterator</code>-Objekt implementiert das Iterator-Protokoll über eine <code>next()</code>-Methode und ermöglicht schrittweises Durchlaufen von Sequenzen.

seit JavaScript ES2015 (Protokoll); Iterator-Hilfsklasse: ES2025 / Kategorie: core

Signatur

class Iterator

Beschreibung

Das Iterator-Protokoll ist das Herzstück der iterierbaren Datenstrukturen in JavaScript. Ein Objekt gilt als Iterator, wenn es eine next()-Methode besitzt, die bei jedem Aufruf ein Ergebnisobjekt der Form { value, done } zurückgibt. Sobald done den Wert true annimmt, ist die Sequenz erschöpft.

Seit ES2025 existiert die eingebaute Klasse Iterator als abstrakte Basisklasse, von der eigene Iteratoren abgeleitet werden können. Sie stellt nützliche Hilfsmethoden bereit wie map(), filter(), take(), drop(), flatMap(), reduce(), toArray() und mehr – ähnlich wie Array-Methoden, aber lazy (d. h. Elemente werden erst bei Bedarf erzeugt).

Iteratoren werden implizit überall dort eingesetzt, wo JavaScript über Sequenzen iteriert: in for...of-Schleifen, beim Spread-Operator ..., bei der Destrukturierung, sowie in Array.from() und Promise.all(). Eigene Iteratoren erstellt man entweder durch Implementierung des Protokolls direkt, durch Generator-Funktionen oder durch Ableitung von der Basisklasse Iterator.

Beim Implementieren eines eigenen Iterators sollte das Objekt zusätzlich das Iterable-Protokoll erfüllen, indem [Symbol.iterator]() this zurückgibt – so ist das Objekt gleichzeitig Iterable und Iterator (Iterable-Iterator).

Rückgabewert

Typ
Iterator
Beschreibung
Iterator ist eine abstrakte Basisklasse und wird nicht direkt instanziiert. Konkrete Iteratoren entstehen durch Unterklassen oder das Iterator-Protokoll.

Beispiele

Eigenen Iterator manuell implementieren

// Iterable-Iterator für eine Zahlenspanne
const range = (start, end) => ({
  [Symbol.iterator]() { return this; },
  current: start,
  next() {
    if (this.current <= end) {
      return { value: this.current++, done: false };
    }
    return { value: undefined, done: true };
  }
});

const r = range(1, 5);
for (const n of r) {
  console.log(n);
}
1 2 3 4 5

Generator als Iterator (empfohlener Stil)

// Generator-Funktion erzeugt automatisch einen Iterator
function* fibonacci() {
  let [a, b] = [0, 1];
  while (true) {
    yield a;
    [a, b] = [b, a + b];
  }
}

const fib = fibonacci();
console.log(fib.next()); // { value: 0, done: false }
console.log(fib.next()); // { value: 1, done: false }
console.log(fib.next()); // { value: 1, done: false }
console.log(fib.next()); // { value: 2, done: false }
{ value: 0, done: false } { value: 1, done: false } { value: 1, done: false } { value: 2, done: false }

Iterator-Hilfsmethoden (ES2025)

// Iterator.from() + lazy map/filter/take (ES2025)
const result = Iterator.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .filter(n => n % 2 === 0)
  .map(n => n ** 2)
  .take(3)
  .toArray();

console.log(result);
[4, 16, 36]

Von Iterator ableiten (ES2025)

// Eigene lazy Sequenz als Unterklasse von Iterator
class Counter extends Iterator {
  #current;
  #max;

  constructor(max) {
    super();
    this.#current = 0;
    this.#max = max;
  }

  next() {
    if (this.#current < this.#max) {
      return { value: this.#current++, done: false };
    }
    return { value: undefined, done: true };
  }
}

const counter = new Counter(5);
console.log(counter.map(x => x * 10).toArray());
[0, 10, 20, 30, 40]

// Wichtig · Fallstricke

Browser-Kompatibilität: Das Iterator-Protokoll (d. h. next(), { value, done }) ist seit ES2015 in allen modernen Browsern verfügbar. Die eingebaute Klasse Iterator mit ihren Hilfsmethoden (map, filter, take usw.) ist jedoch erst ab Chrome 122, Firefox 131 und Safari 18 (2024/2025) verfügbar – für ältere Umgebungen ist ein Polyfill erforderlich.

  • done: true signalisiert das Ende der Sequenz; nachfolgende Aufrufe von next() sollten weiterhin { value: undefined, done: true } zurückgeben.
  • Iteratoren sind einmalig konsumierbar: Im Gegensatz zu Iterables können sie nicht neu gestartet werden. Für mehrfaches Durchlaufen muss ein neuer Iterator erzeugt werden.
  • Die optionale Methode return(value) ermöglicht vorzeitiges Beenden (z. B. beim Verlassen einer for...of-Schleife), throw(error) erlaubt das Injizieren von Fehlern – beide sind im Iterator-Protokoll optional.
  • Generator-Funktionen (function*) sind der komfortabelste Weg, Iteratoren zu erzeugen, da sie das Protokoll automatisch korrekt implementieren.