В ответ на оригинальный вопрос, вы используете for/in
неправильно. В вашем коде key
есть индекс. Итак, чтобы получить значение из псевдомассива, вам нужно сделать, list[key]
а чтобы получить идентификатор, вам нужно list[key].id
. Но вы не должны делать это с for/in
самого начала.
Резюме (добавлено в декабре 2018 г.)
Никогда не используйте for/in
для итерации nodeList или HTMLCollection. Причины, чтобы избежать этого, описаны ниже.
Все последние версии современных браузеров (Safari, Firefox, Chrome, Edge) поддерживают for/of
итерацию в списках DOM, таких как nodeList
или HTMLCollection
.
Вот пример:
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Чтобы включить старые браузеры (включая такие, как IE), это будет работать везде:
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Пояснение, почему вы не должны использовать for/in
for/in
предназначен для итерации свойств объекта. Это означает, что он вернет все итерируемые свойства объекта. Хотя может показаться, что он работает для массива (возвращая элементы массива или элементы псевдомассива), он также может возвращать другие свойства объекта, отличные от ожидаемых от элементов, подобных массиву. И, угадайте, что, HTMLCollection
и nodeList
объект или оба могут иметь другие свойства, которые будут возвращены с for/in
итерацией. Я просто попытался это в Chrome и итерация его так , как вы итерация будет извлекать элементы в списке (индексы 0, 1, 2, и т.д ...), но также будет получать length
и item
свойства. for/in
Итерация просто не будет работать для HTMLCollection.
Смотрите http://jsfiddle.net/jfriend00/FzZ2H/ почему вы не можете перебирать в HTMLCollection с for/in
.
В Firefox ваша for/in
итерация будет возвращать эти элементы (все итерируемые свойства объекта):
0
1
2
item
namedItem
@@iterator
length
Надеюсь, теперь вы можете понять, почему вы хотите использовать for (var i = 0; i < list.length; i++)
вместо этого, чтобы вы просто получили 0
, 1
и 2
в вашей итерации.
Ниже приводится эволюция эволюции браузеров за период 2015-2018 гг., Которая дает вам дополнительные способы итерации. В современных браузерах ничего из этого не требуется, поскольку вы можете использовать опции, описанные выше.
Обновление для ES6 в 2015 году
В ES6 добавлено то, Array.from()
что преобразовать массивоподобную структуру в реальный массив. Это позволяет прямо перечислять список следующим образом:
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Рабочая демонстрация (в Firefox, Chrome и Edge на апрель 2016 г.): https://jsfiddle.net/jfriend00/8ar4xn2s/
Обновление для ES6 в 2016 году
Теперь вы можете использовать ES6 для / of конструкции с a NodeList
и a HTMLCollection
, просто добавив это в ваш код:
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Затем вы можете сделать:
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
Это работает в текущей версии Chrome, Firefox и Edge. Это работает, потому что он присоединяет итератор Array к прототипам NodeList и HTMLCollection, так что, когда for / of итерирует их, он использует итератор Array для их итерации.
Рабочая демонстрация: http://jsfiddle.net/jfriend00/joy06u4e/ .
Второе обновление для ES6 в декабре 2016 года
По состоянию на декабрь 2016 года Symbol.iterator
поддержка была встроена в Chrome v54 и Firefox v50, поэтому приведенный ниже код работает сам по себе. Он еще не встроен в Edge.
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Рабочая демонстрация (в Chrome и Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/
Третье обновление для ES6 в декабре 2017 года
По состоянию на декабрь 2017 года эта возможность работает в Edge 41.16299.15.0 для « nodeList
как в» document.querySelectorAll()
, но не для « HTMLCollection
как в», document.getElementsByClassName()
поэтому вам нужно вручную назначить итератор, чтобы использовать его в Edge для HTMLCollection
. Это загадка, почему они исправляют один тип коллекции, а не другой. Но вы можете по крайней мере использовать результат document.querySelectorAll()
с for/of
синтаксисом ES6 в текущих версиях Edge сейчас.
Я также обновил вышеупомянутый jsFiddle, чтобы он тестировал HTMLCollection
и nodeList
отдельно, и захватывал выходные данные в самом jsFiddle.
Четвертое обновление для ES6 в марте 2018 года
Per mesqueeeb, Symbol.iterator
поддержка была встроена в Safari, так что вы можете использовать for (let item of list)
для любой document.getElementsByClassName()
илиdocument.querySelectorAll()
.
Пятое обновление для ES6 в апреле 2018 года
По-видимому, поддержка итерации HTMLCollection
с for/of
будет приходить в Edge 18 осенью 2018 года.
Шестое обновление для ES6 в ноябре 2018 года
Я могу подтвердить, что с Microsoft Edge v18 (которая включена в Windows Update 2018 года) теперь вы можете перебирать HTMLCollection и NodeList с for / of в Edge.
Итак, теперь все современные браузеры содержат встроенную поддержку for/of
итерации объектов HTMLCollection и NodeList.