En respuesta a la pregunta original, está utilizando for/in
incorrectamente. En su código, key
es el índice. Entonces, para obtener el valor de la pseudo-matriz, tendría que hacer list[key]
y para obtener la identificación, lo haría list[key].id
. Pero, no deberías estar haciendo esto for/in
en primer lugar.
Resumen (agregado en diciembre de 2018)
No lo use nunca for/in
para iterar una lista de nodos o una colección HTMLC. Las razones para evitarlo se describen a continuación.
Todas las versiones recientes de los navegadores modernos (Safari, Firefox, Chrome, Edge) admiten la for/of
iteración en listas DOM como nodeList
o HTMLCollection
.
Aquí hay un ejemplo:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Para incluir navegadores antiguos (incluidos elementos como IE), esto funcionará en todas partes:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Explicación de por qué no debe usar for/in
for/in
está destinado a iterar las propiedades de un objeto. Eso significa que devolverá todas las propiedades iterables de un objeto. Si bien puede parecer que funciona para una matriz (elementos de matriz devueltos o elementos de pseudo-matriz), también puede devolver otras propiedades del objeto que no son lo que espera de los elementos tipo matriz. Y, adivina qué, una HTMLCollection
o nodeList
objeto puede tener tanto otras propiedades que serán devueltos con una for/in
iteración. Acabo de probar esto en Chrome e iterarlo de la forma en que lo hiciste recuperará los elementos de la lista (índices 0, 1, 2, etc.), pero también recuperará las propiedades length
y item
. La for/in
iteración simplemente no funcionará para una colección HTMLC.
Consulte http://jsfiddle.net/jfriend00/FzZ2H/ para ver por qué no puede iterar una colección HTMLC con for/in
.
En Firefox, su for/in
iteración devolvería estos elementos (todas las propiedades iterables del objeto):
0
1
2
item
namedItem
@@iterator
length
Con suerte, ahora puedes ver por qué quieres usar for (var i = 0; i < list.length; i++)
en su lugar, así que solo obtienes 0
, 1
y 2
en tu iteración.
A continuación se muestra una evolución de cómo los navegadores han evolucionado durante el período 2015-2018, ofreciéndole formas adicionales de iterar. Ninguno de estos ahora es necesario en los navegadores modernos, ya que puede usar las opciones descritas anteriormente.
Actualización para ES6 en 2015
Se agregó a ES6 Array.from()
que convertirá una estructura tipo matriz en una matriz real. Eso le permite a uno enumerar una lista directamente así:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Demostración de trabajo (en Firefox, Chrome y Edge a partir de abril de 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/
Actualización para ES6 en 2016
Ahora puede usar el ES6 para / of construct con a NodeList
y an HTMLCollection
simplemente agregando esto a su código:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Entonces, puedes hacer:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Esto funciona en la versión actual de Chrome, Firefox y Edge. Esto funciona porque une el iterador de matriz a los prototipos de NodeList y HTMLCollection para que cuando for / of los itere, use el iterador de matriz para iterarlos.
Demostración de trabajo: http://jsfiddle.net/jfriend00/joy06u4e/ .
Segunda actualización para ES6 en diciembre de 2016
A partir de diciembre de 2016, el Symbol.iterator
soporte se ha incorporado a Chrome v54 y Firefox v50, por lo que el siguiente código funciona por sí solo. Todavía no está integrado para Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Demostración de trabajo (en Chrome y Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Tercera actualización para ES6 en diciembre de 2017
A partir de diciembre de 2017, esta capacidad funciona en Edge 41.16299.15.0 para un nodeList
as in document.querySelectorAll()
, pero no un HTMLCollection
as in, document.getElementsByClassName()
por lo que debe asignar manualmente el iterador para usarlo en Edge para un HTMLCollection
. Es un misterio total por qué arreglarían un tipo de colección, pero no el otro. Pero, al menos puede usar el resultado de la sintaxis document.querySelectorAll()
ES6 for/of
en las versiones actuales de Edge ahora.
También actualicé el jsFiddle anterior para que pruebe ambos HTMLCollection
y por nodeList
separado y capture la salida en el propio jsFiddle.
Cuarta actualización para ES6 en marzo de 2018
Según mesqueeeb, el Symbol.iterator
soporte también se ha incorporado a Safari, por lo que puede usarlo for (let item of list)
para document.getElementsByClassName()
o document.querySelectorAll()
.
Quinta actualización para ES6 en abril de 2018
Aparentemente, el soporte para iterar un HTMLCollection
con for/of
llegará a Edge 18 en el otoño de 2018.
Sexta actualización para ES6 en noviembre de 2018
Puedo confirmar que con Microsoft Edge v18 (que se incluye en la actualización de Windows de otoño de 2018), ahora puede iterar tanto una colección HTMLC como una NodeList con for / of en Edge.
Por lo tanto, ahora todos los navegadores modernos contienen soporte nativo para la for/of
iteración de los objetos HTMLCollection y NodeList.