Signatur
Beschreibung
Iterator.prototype.forEach() gehört zu den Iterator Helpers und funktioniert ähnlich wie Array.prototype.forEach(), arbeitet aber direkt auf einem Iterator. Für jeden Wert, den next() liefert, wird callbackFn einmal aufgerufen. Sie bekommt den Wert und einen fortlaufenden Zähler (counter), der bei 0 beginnt.
Die Methode ist praktisch, wenn du Nebeneffekte auf Werte aus Generatoren, Map-/Set-Iteratoren oder verketteten Iterator-Helpern (map(), filter(), take() …) ausführen willst. Ein Zwischen-Array brauchst du dafür nicht: Die Werte werden einzeln angefordert und verarbeitet. Das spart Speicher und funktioniert auch mit sehr großen Datenquellen.
Anders als die Helper map() oder filter() ist forEach() nicht lazy. Die Methode verbraucht den Iterator sofort und vollständig und gibt undefined zurück. Danach ist der Iterator erschöpft und lässt sich nicht noch einmal durchlaufen.
Einen vorzeitigen Abbruch wie mit break gibt es nicht. Brauchst du einen, nimm eine for...of-Schleife oder Iterator.prototype.some() bzw. find(). Wirft die Callback-Funktion einen Fehler, wird return() des zugrunde liegenden Iterators aufgerufen (falls vorhanden), damit Ressourcen freigegeben werden, und der Fehler wird weitergegeben.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $callbackFn Pflicht | (value: any, counter: number) => void | Funktion, die für jedes Element aufgerufen wird. Ihr Rückgabewert wird ignoriert. Argumente: value ist das aktuelle Element, counter der nullbasierte Index des Elements innerhalb dieses Durchlaufs. |
Beispiele
Werte eines Generators ausgeben
function* fibonacci() {
let [a, b] = [0, 1];
while (true) {
yield a;
[a, b] = [b, a + b];
}
}
// take() begrenzt den unendlichen Iterator, forEach() verbraucht ihn
fibonacci()
.take(6)
.forEach((zahl, i) => console.log(`#${i}: ${zahl}`));
Map-Einträge filtern und verarbeiten ohne Zwischen-Array
const lagerbestand = new Map([
['Schrauben', 120],
['Muttern', 0],
['Dübel', 45],
['Nägel', 0]
]);
lagerbestand
.entries()
.filter(([, menge]) => menge === 0)
.map(([artikel]) => artikel)
.forEach((artikel) => console.log(`Nachbestellen: ${artikel}`));
Rückgabewert und Erschöpfung des Iterators
const iter = ['a', 'b', 'c'].values();
const ergebnis = iter.forEach((buchstabe) => console.log(buchstabe.toUpperCase()));
console.log(ergebnis); // undefined
// Der Iterator ist jetzt verbraucht
console.log(iter.next()); // { value: undefined, done: true }
Beliebiges Iterable per Iterator.from() nutzen
// Ein eigenes Objekt mit next(), das nicht von Iterator.prototype erbt
const countdown = {
n: 3,
next() {
return this.n > 0
? { value: this.n--, done: false }
: { value: undefined, done: true };
}
};
Iterator.from(countdown).forEach((n) => console.log(`${n}…`));
// Wichtig · Fallstricke
- Kein Abbruch möglich:
breakundreturnfunktionieren in der Callback-Funktion nicht als Schleifenabbruch.returnüberspringt nur das aktuelle Element. Für einen Abbruch nimmfor...of,some()oderfind(). - Nicht lazy: Bei einem unendlichen Iterator (z. B. einem Generator mit
while (true)) läuftforEach()endlos, wenn du vorher nicht mittake()begrenzt. - Einmalig: Danach ist der Iterator erschöpft. Ein zweiter Aufruf von
forEach()auf demselben Iterator ruft die Callback-Funktion nicht mehr auf. - Kein
thisArg: Anders alsArray.prototype.forEach()gibt es keinen zweiten Parameter fürthis. Nimm Pfeilfunktionen oderbind(). - Keine Unterstützung für async: Gibt die Callback-Funktion ein Promise zurück, wird es nicht abgewartet. Für asynchrone Verarbeitung nimm
for await...of. Asynchrone Iterator-Helper sind noch in Arbeit. - Kompatibilität: Iterator Helpers gibt es ab Chrome/Edge 122, Firefox 131, Safari 18.4 und Node.js 22. Ältere Umgebungen brauchen ein Polyfill (z. B.
core-js). Objekte, die nicht vonIterator.prototypeerben, musst du vorher mitIterator.from()umwandeln. - Ist
callbackFnkeine Funktion, wird sofort einTypeErrorgeworfen.