Читать книгу JavaScript – Das Handbuch für die Praxis - David Flanagan - Страница 135
5.4.5for/in
ОглавлениеEine for/in-Schleife ähnelt stark einer for/of-Schleife, jedoch mit dem Unterschied, dass das Schlüsselwort of hier in lautet. Während bei einer for/of-Schleife nach dem of ein iterierbares Objekt angegeben werden muss, darf bei einer for/in-Schleife nach dem in jedes beliebige Objekt stehen. Im Gegensatz zur for/of-Schleife, die mit ES6 eingeführt wurde, war for/in von Anfang an Teil von JavaScript (weshalb es die natürlicher klingende Syntax besitzt).
Die for/in-Anweisung durchläuft die Eigenschaftsnamen eines angegebenen Objekts. Die Syntax sieht folgendermaßen aus:
for (Variable in Objekt)
Anweisung
Variable benennt normalerweise eine Variable. Man kann aber auch eine Variablendeklaration verwenden oder alles, das sich als linke Seite eines Zuweisungsausdrucks eignet. Objekt ist ein Ausdruck, der zu einem Objekt auswertet wird. Wie üblich steht Anweisung für die Anweisung oder den Anweisungsblock, der im Schleifenkörper steht.
Sie könnten eine for/in-Schleife beispielsweise so verwenden:
for(let p in o) { // Eigenschaftsnamen von o der Variablen p zuweisen.
console.log(o[p]); // Den Wert der jeweiligen Eigenschaft ausgeben.
}
Bei der Ausführung einer for/in-Anweisung wertet der JavaScript-Interpreter zunächst den Ausdruck Objekt aus. Ergibt die Auswertung null oder undefined, überspringt der Interpreter die Schleife und geht zur nächsten Anweisung über. Ansonsten führt der Interpreter den Inhalt der Schleife für jede Eigenschaft des Objekts einmal aus. Vor jeder Iteration wertet der Interpreter jedoch den Ausdruck Variable aus und weist ihm den Namen der Eigenschaft (einen String) zu.
Beachten Sie bitte, dass in einer for/in-Schleife Variable ein beliebiger Ausdruck sein kann, solange dieser auf der linken Seite einer Zuweisung erlaubt ist. Er wird bei jedem Schleifendurchlauf ausgewertet, kann also bei jedem Schleifendurchlauf ein anderes Ergebnis haben. Sie könnten beispielsweise den folgenden Code benutzen, um die Namen aller Eigenschaften eines Objekts in ein Array zu kopieren:
let o = { x: 1, y: 2, z: 3 };
let a = [], i = 0;
for(a[i++] in o) /* leer*/;
JavaScript-Arrays sind einfach eine spezialisierte Art von Objekt, und Array-Indizes sind Objekteigenschaften, die mit einer for/in-Schleife durchlaufen werden können. Fügen Sie beispielsweise obigem Code am Ende die folgende Zeile hinzu, werden die Array-Indizes 0, 1 und 2 ausgegeben:
for(let i in a) console.log(i);
Mir ist in meinem eigenen Code als häufige Fehlerquelle aufgefallen, dass ich bei Arrays oft versehentlich for/in verwende, obwohl ich eigentlich for/of beabsichtigt hatte. Wenn Sie mit Arrays arbeiten, ist fast immer for/of die bessere Wahl als for/in.
Aber die for/in-Schleife durchläuft nicht alle Eigenschaften eines Objekts. Zum einen werden keine Eigenschaften durchlaufen, deren Namen Symbole sind. Und von den Eigenschaften, deren Namen Zeichenketten sind, werden nur die aufzählbaren (enumerable) Eigenschaften durchlaufen (siehe 14.1). Die diversen integrierten Methoden, die zum Sprachkern von JavaScript gehören, sind nicht aufzählbar. Obwohl alle Objekte beispielsweise eine toString()-Methode haben, wird diese von der for/in-Schleife übersprungen. Neben den eingebauten Methoden ist auch eine Reihe weiterer Eigenschaften der integrierten Objekte nicht aufzählbar. Alle Eigenschaften und Methoden, die von Ihrem Code definiert werden, sind hingegen aufzählbar. (Sie können sie mit Techniken, die in 14.1 erläutert werden, nicht aufzählbar machen.)
Geerbte aufzählbare Eigenschaften (siehe 6.3.2) werden ebenfalls von der for/in-Schleife berücksichtigt. Verwenden Sie for/in-Schleifen zusammen mit Code, in dem Eigenschaften definiert werden, die allen Objekten vererbt werden, verhält sich Ihre Schleife möglicherweise unerwartet. Deshalb ziehen es viele Programmierer vor, eine for/of-Schleife mit Object.keys() anstelle einer for/in-Schleife zu verwenden.
Wenn der Körper einer for/in-Schleife eine Eigenschaft löscht, die noch nicht durchlaufen wurde, wird diese Eigenschaft nicht durchlaufen (weil die Eigenschaften »live« durchlaufen werden und nicht basierend auf einer zuvor einmalig abgerufenen statischen Zusammenstellung der Eigenschaften). Definiert der Inhalt der Schleife neue Eigenschaften des Objekts, werden diese möglicherweise durchlaufen, möglicherweise aber auch nicht. (Das Verhalten der for/in-Schleife ist in seltenen Grenzfällen durch die Sprachspezifikation nicht abschließend vorgegeben.) In 6.6.1 finden Sie weitere Informationen zur Reihenfolge, in der for/in die Eigenschaften eines Objekts aufzählt.