W odpowiedzi na oryginalne pytanie używasz for/in
nieprawidłowo. W twoim kodzie key
jest indeks. Tak więc, aby uzyskać wartość z pseudo-tablicy, musiałbyś to zrobić, list[key]
a żeby uzyskać identyfikator, zrobiłbyś to list[key].id
. Ale for/in
przede wszystkim nie powinieneś tego robić .
Podsumowanie (dodano w grudniu 2018 r.)
Nigdy nie używaj for/in
do iteracji nodeList lub HTMLCollection. Powody, dla których można tego uniknąć, opisano poniżej.
Wszystkie najnowsze wersje nowoczesnych przeglądarek (Safari, Firefox, Chrome, Krawędź) wszelkie wsparcie for/of
iteracja na DOM wymienia takie nodeList
lub HTMLCollection
.
Oto przykład:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Aby uwzględnić starsze przeglądarki (w tym takie jak IE), będzie to działać wszędzie:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Wyjaśnienie, dlaczego nie powinieneś używać for/in
for/in
służy do iteracji właściwości obiektu. Oznacza to, że zwróci wszystkie iterowalne właściwości obiektu. Chociaż może się wydawać, że działa dla tablicy (zwraca elementy tablicy lub elementy pseudo-tablicy), może również zwracać inne właściwości obiektu, które nie są tym, czego oczekujesz od elementów podobnych do tablicy. I zgadnij, co, HTMLCollection
albo nodeList
obiekt może mieć inne właściwości, które zostaną zwrócone z for/in
iteracją. Właśnie próbowałem tego w Chrome i iteracja w taki sposób, w jaki iterowałeś, pobierze elementy z listy (indeksy 0, 1, 2 itd.), Ale także pobierze właściwości length
i item
. for/in
Iteracja po prostu nie będzie działać na HTMLCollection.
Zobacz http://jsfiddle.net/jfriend00/FzZ2H/, aby dowiedzieć się, dlaczego nie możesz iterować kolekcji HTMLCollection for/in
.
W przeglądarce Firefox twoja for/in
iteracja zwróciłaby te elementy (wszystkie iterowalne właściwości obiektu):
0
1
2
item
namedItem
@@iterator
length
Mam nadzieję, że teraz można zobaczyć, dlaczego chcesz używać for (var i = 0; i < list.length; i++)
zamiast tak po prostu dostać 0
, 1
a 2
w iteracji.
Poniżej znajduje się ewolucja ewolucji przeglądarek w okresie 2015-2018, co daje dodatkowe możliwości iteracji. Żadne z nich nie są teraz potrzebne w nowoczesnych przeglądarkach, ponieważ możesz skorzystać z opcji opisanych powyżej.
Aktualizacja dla ES6 w 2015 roku
Dodano do ES6 to, Array.from()
że konwertuje strukturę podobną do tablicy na rzeczywistą tablicę. To pozwala wyliczyć listę bezpośrednio w ten sposób:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Działające demo (w Firefox, Chrome i Edge od kwietnia 2016 r.): Https://jsfiddle.net/jfriend00/8ar4xn2s/
Aktualizacja dla ES6 w 2016 roku
Możesz teraz używać ES6 dla / z konstruktem za pomocą a NodeList
i HTMLCollection
po prostu dodając to do swojego kodu:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Następnie możesz wykonać:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Działa to w bieżącej wersji Chrome, Firefox i Edge. Działa to, ponieważ dołącza iterator Array zarówno do prototypów NodeList, jak i HTMLCollection, dzięki czemu podczas ich iteracji używa iteratora Array do iteracji.
Działające demo: http://jsfiddle.net/jfriend00/joy06u4e/ .
Druga aktualizacja ES6 w grudniu 2016 r
Od grudnia 2016 r. Symbol.iterator
Obsługa Chrome jest wbudowana w Chrome v54 i Firefox v50, więc poniższy kod działa sam. Nie jest jeszcze wbudowany w Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Działające demo (w Chrome i Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Trzecia aktualizacja ES6 w grudniu 2017 r
Od grudnia 2017 r. Ta funkcja działa w Edge 41.16299.15.0 dla wersji nodeList
as document.querySelectorAll()
, ale nie dla wersji HTMLCollection
as, document.getElementsByClassName()
więc musisz ręcznie przypisać iterator do użycia w Edge dla wersji HTMLCollection
. Jest całkowitą tajemnicą, dlaczego naprawili jeden typ kolekcji, ale nie drugi. Ale teraz możesz przynajmniej użyć wyniku document.querySelectorAll()
ze for/of
składnią ES6 w bieżących wersjach Edge.
Ja również zaktualizowane wyżej jsFiddle więc testuje zarówno HTMLCollection
i nodeList
osobno i oddaje moc w samej jsFiddle.
Czwarta aktualizacja ES6 w marcu 2018 r
W przypadku mesqueeeb Symbol.iterator
obsługa Safari została również wbudowana, dzięki czemu można korzystać for (let item of list)
z jednego document.getElementsByClassName()
lub drugiego document.querySelectorAll()
.
Piąta aktualizacja ES6 w kwietniu 2018 r
Najwyraźniej wsparcie dla iteracji HTMLCollection
z for/of
pojawi się na Edge 18 jesienią 2018 r.
Szósta aktualizacja ES6 w listopadzie 2018 r
Mogę potwierdzić, że dzięki Microsoft Edge v18 (który jest zawarty w Windows Update Fall 2018), możesz teraz iterować zarówno HTMLCollection, jak i NodeList z for / of w Edge.
Tak więc teraz wszystkie nowoczesne przeglądarki zawierają natywną obsługę for/of
iteracji zarówno obiektów HTMLCollection, jak i NodeList.