У відповідь на оригінальне запитання ви використовуєте for/in
неправильно. У вашому коді key
є індекс. Отже, щоб отримати значення з псевдомасиву, вам доведеться зробити list[key]
і отримати ідентифікатор, який ви зробили б list[key].id
. Але, for/in
в першу чергу, не варто цього робити .
Підсумок (додано у грудні 2018 р.)
Ніколи не використовуйте for/in
для ітерації nodeList або HTMLCollection. Причини цього уникати описані нижче.
Всі останні версії сучасних браузерів (Safari, Firefox, Chrome, краю) все підтримують 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 construct з a NodeList
і an 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. Це працює, тому що він приєднує ітератор масиву як до прототипів NodeList, так і для HTMLCollection, так що при / для ітерацій він використовує ітератор масиву для ітерації.
Робоча демонстрація: 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
як in, document.getElementsByClassName()
тому вам доведеться вручну призначити ітератор, щоб використовувати його в Edge для HTMLCollection
. Загальна загадка, чому вони виправили один тип колекції, а не інший. Але ви можете принаймні використовувати результат синтаксису document.querySelectorAll()
ES6 for/of
у поточних версіях Edge зараз.
Я також оновив вищевказаний jsFiddle, щоб він перевіряв HTMLCollection
і nodeList
окремо, і фіксує вихід у самому jsFiddle.
Четверте оновлення для ES6 у березні 2018 року
За програмою Mesqueeeb Symbol.iterator
в Safari також вбудована підтримка, тому ви можете використовувати for (let item of list)
будь-яку document.getElementsByClassName()
або document.querySelectorAll()
.
П'яте оновлення для ES6 у квітні 2018 року
По- видимому, підтримка перебору HTMLCollection
з for/of
приходитиме до краю 18 осені 2018 року.
Шосте оновлення для ES6 у листопаді 2018 року
Я можу підтвердити, що за допомогою Microsoft Edge v18 (що включено в Осіннє оновлення Windows 2018) тепер ви можете переглядати як HTMLCollection, так і NodeList з для / в Edge.
Отже, тепер усі сучасні браузери містять вбудовану підтримку for/of
ітерації як об’єктів HTMLCollection, так і NodeList.