Die for…in-Schleife – Programmieren lernen mit JavaScript – Thytos
Nächstes Video startet in 3 Sekunden.
Programmieren lernen mit JavaScript

Die for…in-Schleife

Die for…in-Schlei­fe wirkt per­fekt für Ar­rays, aber sie ist von al­len Schlei­fen mit Ab­stand die lang­sam­ste, denn sie ist für ei­nen an­de­ren Zweck bestimmt.

Um durch ein Array zu iterieren, macht von allen Schleifenarten die for…in-Schleife die geringste Schreibarbeit. Wenn ihr den folgenden Code in eurer Browser-Konsole ausführt, könnt ihr das selbst nachvollziehen.

var arr = "abc".split("");
for (var i in arr) {
  console.log(arr[i]);
}
// Ausgabe:
a
b
c

Mit der split-Funktion wird ein String in ein Array aufgespalten. Anschließend geht die for…in-Schleife über jedes Property und gibt es mit console.log in der Konsole aus.

Das funktioniert alles einfach und sieht zielführend aus, doch es gibt einen großen Nachteil: Die for…in-Schleife ist zur Array-Iteration rund 97% langsamer als alle anderen Schleifen.

Die for-in-Schleife ist bis zu 97% langsamer als andere Schleifen, um Array-Iterationen durchzuführen

Das liegt daran, dass die for…in-Schleife nicht zum Durchlaufen von Arrays gemacht ist, auch wenn sie ideal dafür wirkt.
Aber wofür ist sie dann gemacht?

Die Schleife für Objekte

Statt über ein Array läuft die Schleife im folgenden Beispiel über eine Instanz von CastDatabase.

for (var i in cast) {
  console.log(i);
}
// Ausgabe:
datensatz
insert
where
update
delete

Es funktioniert! Und was passiert, ist: Es werden all die Properties von cast geloggt.

Die for…in-Schleife läuft über alle Properties eines Objekts.

Da Arrays auch Objekte sind, hat das zwar auch bei Arrays funktioniert, aber weil die Schleife auf einen viel allgemeineren Zweck ausgelegt ist, ist sie nicht für die Array-Iteration optimiert.

Wenn ihr sehr aufmerksam seid, sagt ihr vielleicht: Aber Moment! Das length-Property ist auch ein Array-Property, wurde aber von der Schleife nicht durchlaufen! Wie kommt das?

Jedes Objekt besitzt die Methode propertyIsEnumerable die Auskunft darüber gibt, ob die for…in-Schleife über ein bestimmtes Property iterieren darf oder nicht. Für das length-Property eines Arrays gibt diese false zurück.

arr.propertyIsEnumerable("length");
// => false

Die Schleife »darf« also nicht darüber iterieren. Das zeigt aber auch: Vor jedem Schleifen­durchlauf prüft die for…in-Schleife erst einmal, ob das entsprechende Property in der Schleife durchlaufen werden darf oder nicht.

Außerdem: Für die cast-Instanz ist die for…in-Schleife über datensatz und insert, aber auch where, update und delete gelaufen. Letztere sind vererbte Methoden. Das bedeutet, dass die Schleife nicht nur das Objekt selbst durchgeht, sondern anschließend an der Prototypkette entlang auch jedes einzelne Prototypobjekt abgeht.
Kein Wunder also, dass die Schleife für Array-Iteration die langsamste im Vergleich ist. Sie tut viel mehr als die anderen Schleifen.
Um über Objekt-Properties zu gehen, ist sie dagegen die richtige Schleife.

Das globale Objekt

Probiert einmal folgendes in eurer Konsole aus: Schreibt eine for…in-Schleife, aber statt über cast oder ein Array zu laufen, geht this ab. Der Code ist nicht in einer Instanz-Methode – worauf würde sich this also beziehen? Probiert es aus und schaut, was passiert.

for (var i in this) {
  console.log(i);
}

Es funktioniert tatsächlich. Es werden sehr viele Propertynamen ausgegeben. Aber was ist das Objekt, auf das sich this an dieser Stelle bezieht?

this
// => Window {stop: function, open: function, …}

this ist das Objekt des global scope, des globalen Geltungsbereichs.
In Browsern ist das das window-Objekt.
Jede Funktion, die bisher in der Serie benutzt wurde, um etwas auszugeben — also alert oder in diesem Artikel console.log — ist tatsächlich ein Property des window-Objekts!

window.alert === alert
// => true
window.console.log === console.log
// => true

Bei Properties des window-Objekts muss window nicht davor geschrieben werden, weil sie global verfügbar sind.
Aber was genau ist dieses window-Objekt?

Zugriff auf die Webseite

Das window-Objekt steht in gewisser Weise für euer Browser-Fenster — Window heißt ja auch Fenster.
In eurem Browserfenster befindet sich eine Webseite, ein Webdokument. In window gibt es ein Property namens document.

window.document
// => #document

Wenn ihr das in eurer Konsole ausführt, bekommt ihr ein Objekt zurück, das in der Konsole anders als andere JavaScript-Objekte formatiert ist. Wenn ihr mit dem Cursor darüber hovert, wird die Webseite plötzlich mit Blau überlegt.

Wenn ihr HTML könnt, wisst ihr, dass HTML-Dokumente einen <body> besitzen und in diesem mehrere Kindelemente sein können.

document.body.children

Der Wert ist eine Liste. Ihr könnt auf das erste Element in der Liste zugreifen und folgendes schreiben:

document.body.children[0].style.opacity = 0.33;

Die Webseite ist plötzlich transparenter geworden. Um das rückgängig zu machen, entfernt ihr den Wert wieder oder setzt ihn auf 1.

// Rückgängig machen
document.body.children[0].style.opacity = undefined;
// Oder alternativ
document.body.children[0].style.opacity = 1;

Ihr habt damit die Webseite verändert! Ihr könnt auf jedes Element der Webseite zugreifen und es verändern oder entfernen oder auch neue Elemente hinzufügen.
Der Zugriff auf die Elemente funktioniert über eine Programmier­schnitt­stelle, eine API, durch die jedes Element der Webseite in JavaScript durch ein Objekt repräsentiert wird. Die API heißt Document Object Model, abgekürzt DOM.

An dieser Stelle beginnt Frontend-Webentwicklung und endet diese Serie.
Im nächsten Artikel gibt es einen zusammenfassenden Überblick über die gesamte Serie.