Start · Sprachen · JavaScript · Referenz · for...of

for...of

Anweisung

Die <code>for...of</code>-Anweisung führt eine Schleife aus, die über die Werte eines iterable object iteriert.

seit JavaScript ES2015 Kategorie: syntax

Signatur

for (variable of iterable) statement

Beschreibung

Die for...of-Anweisung führt eine Schleife aus, die auf einer Wertefolge operiert, die aus einem iterable object stammt. Zu iterable objects gehören Instanzen von eingebauten Typen wie Array, String, TypedArray, Map, Set, NodeList (und andere DOM-Sammlungen) sowie das arguments-Objekt, generators, die von generator functions erzeugt werden, und benutzerdefinierte iterables.

Eine for...of-Schleife operiert nacheinander in sequentieller Reihenfolge auf den Werten, die aus einem iterable stammen. Jeder Vorgang der Schleife auf einem Wert wird als Iteration bezeichnet, und man sagt, die Schleife iteriert über das iterable. Jede Iteration führt Anweisungen aus, die sich auf den aktuellen Sequenzwert beziehen können.

Wenn eine for...of-Schleife über ein iterable iteriert, ruft sie zuerst die [Symbol.iterator]()-Methode des iterables auf, die einen iterator zurückgibt, und ruft dann wiederholt die next()-Methode des resultierenden iterators auf, um die Wertefolge zu erzeugen, die der variable zugewiesen wird.

Eine for...of-Schleife wird beendet, wenn der iterator abgeschlossen ist (das next()-Ergebnis ist ein Objekt mit done: true). Wie bei anderen Schleifenanweisungen können Sie innerhalb von statement Kontrollfluss-Anweisungen verwenden:

  • break stoppt die Ausführung von statement und geht zur ersten Anweisung nach der Schleife.
  • continue stoppt die Ausführung von statement und geht zur nächsten Iteration der Schleife.

Wenn die for...of-Schleife vorzeitig beendet wird (z. B. wenn eine break-Anweisung erreicht oder ein Fehler geworfen wird), wird die return()-Methode des iterators aufgerufen, um etwaige Aufräumarbeiten durchzuführen.

Der variable-Teil von for...of akzeptiert alles, was vor dem =-Operator stehen kann. Sie können const verwenden, um die Variable zu deklarieren, solange sie innerhalb des Schleifenkörpers nicht neu zugewiesen wird (sie kann sich zwischen Iterationen ändern, da es sich um zwei separate Variablen handelt). Andernfalls können Sie let verwenden.

Mit using oder await using deklarierte Variablen werden bei jeder abgeschlossenen Schleifeniteration disposed (und await using verursacht ein implizites await am Ende der Iteration). Wenn die Schleife jedoch vorzeitig beendet wird, werden Werte, die im iterator verblieben sind und nicht besucht wurden, nicht disposed (der aktuelle Wert allerdings schon).

Sie können destructuring verwenden, um mehrere lokale Variablen zuzuweisen, oder einen Property-Accessor wie for (x.y of iterable), um den Wert einer Objekteigenschaft zuzuweisen.

Eine spezielle Regel verbietet jedoch die Verwendung von async als Variablenname. Dies dient dazu, syntaktische Mehrdeutigkeit mit dem gültigen Code for (async of => {};;) zu vermeiden, der eine for-Schleife ist.

Wenn Sie die using-Deklaration verwenden, darf die Variable ebenfalls nicht of heißen. Dies dient dazu, syntaktische Mehrdeutigkeit mit dem gültigen Code for (using of []) zu vermeiden, der vor der Einführung von using existierte.

Parameter

Name Typ Default Beschreibung
$variable Pflicht any — Empfängt bei jeder Iteration einen Wert aus der Sequenz. Kann entweder eine Deklaration mit const, let, var, using, await using oder ein assignment-Ziel sein (z. B. eine zuvor deklarierte Variable, eine Objekteigenschaft oder ein destructuring pattern). Mit var deklarierte Variablen sind nicht lokal zur Schleife, d. h. sie befinden sich im gleichen Scope wie die for...of-Schleife.
$iterable Pflicht Iterable — Ein iterable object. Die Quelle der Wertefolge, auf der die Schleife operiert.
$statement Pflicht Statement — Eine Anweisung, die bei jeder Iteration ausgeführt wird. Kann auf variable verweisen. Sie können ein block statement verwenden, um mehrere Anweisungen auszuführen.

Rückgabewert

Typ
void
Beschreibung
Die for...of-Anweisung hat keinen Rückgabewert; sie führt den Block für jeden Wert des Iterables aus.

Beispiele

Iteration über ein Array

const iterable = [10, 20, 30];

for (const value of iterable) {
  console.log(value);
}
// 10
// 20
// 30

Iteration über einen String

const iterable = "boo";

for (const value of iterable) {
  console.log(value);
}
// "b"
// "o"
// "o"

Iteration über ein TypedArray

const iterable = new Uint8Array([0x00, 0xff]);

for (const value of iterable) {
  console.log(value);
}
// 0
// 255

Iteration über eine Map

const iterable = new Map([
  ["a", 1],
  ["b", 2],
  ["c", 3],
]);

for (const entry of iterable) {
  console.log(entry);
}
// ['a', 1]
// ['b', 2]
// ['c', 3]

for (const [key, value] of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Iteration über ein Set

const iterable = new Set([1, 1, 2, 2, 3, 3]);

for (const value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Iteration über das arguments-Objekt

function foo() {
  for (const value of arguments) {
    console.log(value);
  }
}

foo(1, 2, 3);
// 1
// 2
// 3

Iteration über eine NodeList

const articleParagraphs = document.querySelectorAll("article > p");
for (const paragraph of articleParagraphs) {
  paragraph.classList.add("read");
}

Iteration über ein benutzerdefiniertes iterable

const iterable = {
  [Symbol.iterator]() {
    let i = 1;
    return {
      next() {
        if (i <= 3) {
          return { value: i++, done: false };
        }
        return { value: undefined, done: true };
      },
    };
  },
};

for (const value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Iteration über ein Objekt mit generator-Methode

const iterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  },
};

for (const value of iterable) {
  console.log(value);
}
// 1
// 2
// 3

Iterable iterator

let i = 1;

const iterator = {
  next() {
    if (i <= 3) {
      return { value: i++, done: false };
    }
    return { value: undefined, done: true };
  },
  [Symbol.iterator]() {
    return this;
  },
};

for (const value of iterator) {
  console.log(value);
}
// 1
// 2
// 3

Iteration über einen generator

function* source() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = source();

for (const value of generator) {
  console.log(value);
}
// 1
// 2
// 3

Vorzeitiges Beenden

const source = [1, 2, 3];

const iterator = source[Symbol.iterator]();

for (const value of iterator) {
  console.log(value);
  if (value === 1) {
    break;
  }
  console.log("This string will not be logged.");
}
// 1

// Another loop using the same iterator
// picks up where the last loop left off.
for (const value of iterator) {
  console.log(value);
}
// 2
// 3

// The iterator is used up.
// This loop will execute no iterations.
for (const value of iterator) {
  console.log(value);
}
// [No output]

Generator wird nach vorzeitigem Abbruch nicht wiederverwendet

function* source() {
  yield 1;
  yield 2;
  yield 3;
}

const generator = source();

for (const value of generator) {
  console.log(value);
  if (value === 1) {
    break;
  }
  console.log("This string will not be logged.");
}
// 1

// The generator is used up.
// This loop will execute no iterations.
for (const value of generator) {
  console.log(value);
}
// [No output]

Unterschied zwischen for...of und for...in

Object.prototype.objCustom = function () {};
Array.prototype.arrCustom = function () {};

const iterable = [3, 5, 7];
iterable.foo = "hello";

for (const i in iterable) {
  console.log(i);
}
// "0", "1", "2", "foo", "arrCustom", "objCustom"

for (const i in iterable) {
  if (Object.hasOwn(iterable, i)) {
    console.log(i);
  }
}
// "0" "1" "2" "foo"

for (const i of iterable) {
  console.log(i);
}
// 3 5 7

// Wichtig · Fallstricke

Jede Iteration erzeugt eine neue Variable. Eine Neuzuweisung der Variable im Schleifenkörper beeinflusst den ursprünglichen Wert im iterable (in diesem Fall ein Array) nicht.