Als Antwort auf die ursprüngliche Frage verwenden Sie for/in
falsch. In Ihrem Code ist key
der Index. Um also den Wert aus dem Pseudo-Array zu erhalten, müssten Sie list[key]
und um die ID zu erhalten, würden Sie list[key].id
verwenden. Aber Sie sollten das sowieso nicht mit for/in
machen.
Zusammenfassung (hinzugefügt im Dez. 2018)
Verwenden Sie niemals for/in
, um eine nodeList oder eine HTMLCollection zu durchlaufen. Die Gründe, dies zu vermeiden, werden unten beschrieben.
Alle aktuellen Versionen der modernen Browser (Safari, Firefox, Chrome, Edge) unterstützen alle die Iteration mit for/of
auf DOM-Listen wie z.B. nodeList
oder HTMLCollection
.
Hier ist ein Beispiel:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Um auch ältere Browser (einschließlich Dinge wie IE) einzuschließen, funktioniert dies überall:
var list = document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //zweite Konsolenausgabe
}
Erklärung, warum Sie for/in
nicht verwenden sollten:
for/in
dient dazu, die Eigenschaften eines Objekts zu durchlaufen. Das bedeutet, dass es alle durchlässigen Eigenschaften eines Objekts zurückgeben wird. Auch wenn es für ein Array zu funktionieren scheint (die Array-Elemente oder Pseudo-Array-Elemente zurückgibt), kann es auch andere Eigenschaften des Objekts zurückgeben, die nicht die erwarteten Array-ähnlichen Elemente sind. Und, raten Sie mal, ein HTMLCollection
- oder nodeList
-Objekt kann auch andere Eigenschaften haben, die bei einer for/in
-Iteration zurückgegeben werden. Ich habe es gerade in Chrome ausprobiert und wenn Sie es so durchlaufen wie Sie es getan haben, werden die Elemente in der Liste (Indexe 0, 1, 2 etc.) zurückgegeben, aber es werden auch die Eigenschaften length
und item
zurückgegeben. Die for/in
-Iteration funktioniert einfach nicht für eine HTMLCollection.
Siehe http://jsfiddle.net/jfriend00/FzZ2H/ warum Sie eine HTMLCollection nicht mit for/in
durchlaufen können.
In Firefox würde Ihre for/in
-Iteration diese Elemente zurückgeben (alle durchlässigen Eigenschaften des Objekts):
0
1
2
item
namedItem
@@iterator
length
Hoffentlich sehen Sie nun, warum Sie stattdessen for (var i = 0; i < list.length; i++)
verwenden möchten, um nur 0
, 1
und 2
Entwicklung der Browserunterstützung für die Iteration von NodeList und HTMLCollection
Nachfolgend finden Sie eine Evolution, wie sich die Browser im Zeitraum 2015-2018 entwickelt haben und Ihnen zusätzliche Möglichkeiten zur Iteration bieten. Keine dieser Möglichkeiten wird in modernen Browsern benötigt, da Sie die oben beschriebenen Optionen verwenden können.
Update für ES6 im Jahr 2015
In ES6 wurde Array.from()
hinzugefügt, das eine array-ähnliche Struktur in ein tatsächliches Array umwandelt. Das ermöglicht es, eine Liste direkt wie folgt aufzuzählen:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Funktionsdemo (in Firefox, Chrome und Edge per April 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Update für ES6 im Jahr 2016
Sie können nun den ES6 for/of-Konstrukt mit einem NodeList
und einer HTMLCollection
verwenden, indem Sie einfach dies zu Ihrem Code hinzufügen:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Dann können Sie folgendes tun:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Dies funktioniert in der aktuellen Version von Chrome, Firefox und Edge. Dies funktioniert, weil es den Array-Iterator an die Prototypen von NodeList und HTMLCollection anhängt, so dass er den Array-Iterator verwendet, um sie zu durchlaufen, wenn for/of sie durchläuft.
Funktionsdemo: http://jsfiddle.net/jfriend00/joy06u4e/.
Zweites Update für ES6 im Dezember 2016
Seit Dezember 2016 ist die Unterstützung für Symbol.iterator
in Chrome v54 und Firefox v50 integriert, so dass der folgende Code von selbst funktioniert. Es ist noch nicht in Edge eingebaut.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Funktionsdemo (in Chrome und Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Drittes Update für ES6 im Dezember 2017
Seit Dezember 2017 funktioniert diese Möglichkeit in Edge 41.16299.15.0 für eine nodeList
wie in document.querySelectorAll()
, nicht jedoch für eine HTMLCollection
wie in document.getElementsByClassName()
, sodass Sie den Iterator manuell zuweisen müssen, um ihn in Edge für eine HTMLCollection
zu verwenden. Es ist ein komplettes Rätsel, warum sie einen Sammlungstyp reparieren würden, aber nicht den anderen. Aber Sie können zumindest das Ergebnis von document.querySelectorAll()
mit der ES6 for/of
-Syntax jetzt in aktuellen Versionen von Edge verwenden.
Ich habe auch das oben genannte jsFiddle aktualisiert, damit es sowohl HTMLCollection
als auch nodeList
getrennt testet und die Ausgabe im jsFiddle selbst erfasst.
Viertes Update für ES6 im März 2018
Laut mesqueeeb ist die Unterstützung für Symbol.iterator
jetzt auch in Safari integriert, so dass Sie for (let item of list)
für sowohl document.getElementsByClassName()
als auch document.querySelectorAll()
verwenden können.
Fünftes Update für ES6 im April 2018
Anscheinend wird die Unterstützung für die Iteration einer HTMLCollection
mit for/of
in Edge 18 im Herbst 2018 kommen.
Sechstes Update für ES6 im November 2018
Ich kann bestätigen, dass mit Microsoft Edge v18 (der im Windows Update im Herbst 2018 enthalten ist) können Sie jetzt sowohl eine HTMLCollection als auch eine NodeList mit for/of in Edge durchlaufen.
Also enthalten jetzt alle modernen Browser native Unterstützung für die Iteration von for/of
sowohl bei den HTMLCollection- als auch NodeList-Objekten.