Menanggapi pertanyaan awal, Anda menggunakan for/in
salah. Dalam kode Anda, key
adalah indeks. Jadi, untuk mendapatkan nilai dari pseudo-array, Anda harus melakukan list[key]
dan mendapatkan id, Anda harus melakukannya list[key].id
. Tapi, Anda seharusnya tidak melakukan hal ini for/in
sejak awal.
Ringkasan (ditambahkan pada Des 2018)
Jangan pernah gunakan for/in
untuk beralih ke nodeList atau HTMLCollection. Alasan untuk menghindarinya dijelaskan di bawah ini.
Semua versi terbaru dari browser modern (Safari, Firefox, Chrome, Edge) semua mendukung for/of
iterasi pada daftar DOM tersebut nodeList
atau HTMLCollection
.
Ini sebuah contoh:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Untuk menyertakan browser yang lebih lama (termasuk hal-hal seperti IE), ini akan berfungsi di mana saja:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Penjelasan Untuk Mengapa Anda Tidak Harus Menggunakan for/in
for/in
dimaksudkan untuk mengulangi properti dari suatu objek. Itu berarti ia akan mengembalikan semua properti yang dapat diubah dari suatu objek. Meskipun ini tampaknya berfungsi untuk sebuah array (mengembalikan elemen array atau elemen pseudo-array), itu juga dapat mengembalikan properti objek lain yang tidak seperti yang Anda harapkan dari elemen seperti array. Dan, coba tebak, suatu HTMLCollection
atau nodeList
objek keduanya bisa memiliki properti lain yang akan dikembalikan dengan for/in
iterasi. Saya baru saja mencoba ini di Chrome dan mengulanginya dengan cara Anda iterasi itu akan mengambil item dalam daftar (indeks 0, 1, 2, dll ...), tetapi juga akan mengambil length
dan item
properti. The for/in
iterasi hanya tidak akan bekerja untuk HTMLCollection.
Lihat http://jsfiddle.net/jfriend00/FzZ2H/ untuk alasan Anda tidak dapat mengulangi HTMLCollection dengan for/in
.
Di Firefox, for/in
iterasi Anda akan mengembalikan item-item ini (semua properti objek yang dapat diulang):
0
1
2
item
namedItem
@@iterator
length
Mudah-mudahan, sekarang Anda dapat melihat mengapa Anda ingin menggunakannya for (var i = 0; i < list.length; i++)
sebagai gantinya sehingga Anda dapatkan 0
, 1
dan 2
dalam iterasi Anda.
Berikut di bawah ini adalah evolusi dari bagaimana browser telah berevolusi selama periode waktu 2015-2018 memberi Anda cara tambahan untuk beralih. Tidak satu pun dari ini sekarang diperlukan di browser modern karena Anda dapat menggunakan opsi yang dijelaskan di atas.
Pembaruan untuk ES6 pada tahun 2015
Ditambahkan ke ES6 Array.from()
yang akan mengubah struktur mirip array ke array yang sebenarnya. Itu memungkinkan seseorang untuk menghitung daftar secara langsung seperti ini:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Demo yang berfungsi (di Firefox, Chrome, dan Edge pada April 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Pembaruan untuk ES6 pada tahun 2016
Anda sekarang dapat menggunakan ES6 untuk / konstruksi dengan a NodeList
dan HTMLCollection
dengan hanya menambahkan ini ke kode Anda:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Kemudian, Anda dapat melakukan:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Ini berfungsi di versi Chrome, Firefox, dan Edge saat ini. Ini berfungsi karena ia melampirkan iterator Array ke prototipe NodeList dan HTMLCollection sehingga ketika / untuk iterate mereka, ia menggunakan iterator Array untuk iterate mereka.
Demo kerja: http://jsfiddle.net/jfriend00/joy06u4e/ .
Pembaruan kedua untuk ES6 pada Desember 2016
Pada Desember 2016, Symbol.iterator
dukungan telah terpasang di dalam Chrome v54 dan Firefox v50 sehingga kode di bawah ini bekerja dengan sendirinya. Itu belum built-in untuk Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Demo yang berfungsi (di Chrome dan Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Pembaruan ketiga untuk ES6 pada bulan Desember 2017
Pada Desember 2017, kemampuan ini bekerja di Edge 41.16299.15.0 untuk a nodeList
sebagai in document.querySelectorAll()
, tetapi bukan HTMLCollection
sebagai in document.getElementsByClassName()
sehingga Anda harus menetapkan secara manual iterator untuk menggunakannya di Edge untuk sebuah HTMLCollection
. Ini adalah misteri total mengapa mereka memperbaiki satu jenis koleksi, tetapi tidak yang lain. Tapi, Anda setidaknya dapat menggunakan hasil document.querySelectorAll()
dengan for/of
sintaks ES6 di versi Edge sekarang.
Saya juga memperbarui jsFiddle di atas sehingga ia menguji keduanya HTMLCollection
dan nodeList
secara terpisah dan menangkap output di jsFiddle itu sendiri.
Pembaruan Keempat untuk ES6 pada Maret 2018
Per mesqueeeb, Symbol.iterator
dukungan telah built-in ke Safari juga, sehingga Anda dapat menggunakan for (let item of list)
salah satu document.getElementsByClassName()
atau document.querySelectorAll()
.
Pembaruan Kelima untuk ES6 pada bulan April 2018
Rupanya, dukungan untuk iterasi HTMLCollection
dengan for/of
akan datang ke Edge 18 pada musim gugur 2018.
Pembaruan Keenam untuk ES6 pada November 2018
Saya dapat mengonfirmasi bahwa dengan Microsoft Edge v18 (yang termasuk dalam Pembaruan Windows Musim Gugur 2018), Anda sekarang dapat melakukan iterasi HTMLCollection dan NodeList dengan for / of in Edge.
Jadi, sekarang semua browser modern berisi dukungan asli untuk for/of
iterasi dari objek HTMLCollection dan NodeList.