Welche Schleife passt, hängt davon ab, worüber du iterierst: über Indizes, über die Werte eines Iterables, über die Schlüssel eines Objekts oder über asynchrone Daten.
for und while
Die klassische for-Schleife nimmst du, wenn du den Index brauchst. while prüft die Bedingung vor jedem Durchlauf. do…while läuft mindestens einmal.
for (let i = 0; i < 3; i++) {
console.log(i); // 0, 1, 2
}
let n = 3;
while (n > 0) n--;
Verwende let statt var. Nur mit let bekommt jede Iteration eine eigene Bindung. Das ist wichtig bei Closures, zum Beispiel in setTimeout.
for…of vs. for…in
for…of durchläuft die Werte von Iterables wie Array, String, Map, Set oder NodeList. for…in durchläuft die aufzählbaren Schlüssel eines Objekts, auch geerbte. Für Arrays ist for…in deshalb ungeeignet.
const farben = ['rot', 'grün'];
for (const [i, farbe] of farben.entries()) {
console.log(`${i}: ${farbe}`);
}
const user = { name: 'Ada', rolle: 'admin' };
for (const [key, value] of Object.entries(user)) {
console.log(`${key} = ${value}`);
}
Object.entries() zusammen mit for…of ist meist sauberer als for…in, weil nur eigene Eigenschaften vorkommen.
break, continue und Labels
break beendet die Schleife. continue springt direkt zur nächsten Iteration. Mit einem Label kannst du auch verschachtelte Schleifen gezielt verlassen.
aussen: for (const zeile of matrix) {
for (const zelle of zeile) {
if (zelle === null) continue;
if (zelle === 0) break aussen;
}
}
Achtung: forEach() kennt kein break. Wenn du vorzeitig abbrechen willst, nimm for…of, some() oder find().
Asynchron: await in Schleifen
await in for…of arbeitet die Schritte nacheinander ab. Für asynchrone Iterables wie Streams oder Async-Generatoren gibt es for await…of.
async function* zaehler() {
yield 1;
yield 2;
}
for await (const wert of zaehler()) console.log(wert);
// parallel statt nacheinander:
const daten = await Promise.all(urls.map((u) => fetch(u)));
Ein häufiger Fehler: await in einem forEach()-Callback wartet nicht. Die Schleife läuft sofort weiter.