In response to the original question, you are using for/in
incorrectly.(在回答原始问题时,您使用for/in
不正确的for/in
。)
In your code, key
is the index.(在您的代码中, key
是索引。) So, to get the value from the pseudo-array, you'd have to do list[key]
and to get the id, you'd do list[key].id
.(因此,要从伪数组中获取值,您必须执行list[key]
并获取ID,您必须执行list[key].id
。) But, you should not be doing this with for/in
in the first place.(但是,您不应该首先使用for/in
进行此操作。)
Summary (added in Dec 2018)(摘要(于2018年12月新增))
Do not ever use for/in
to iterate a nodeList or an HTMLCollection.(永远不要使用for/in
来迭代nodeList或HTMLCollection。)
The reasons to avoid it are described below.(避免这种情况的原因如下所述。)
All recent versions of modern browsers (Safari, Firefox, Chrome, Edge) all support for/of
iteration on DOM lists such nodeList
or HTMLCollection
.(现代浏览器的所有最新版本(Safari,Firefox,Chrome,Edge)都支持DOM列表上for/of
迭代,例如nodeList
或HTMLCollection
。)
Here's an example:(这是一个例子:)
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
To include older browsers (including things like IE), this will work everywhere:(要包括较旧的浏览器(包括IE之类的东西),它将在任何地方都适用:)
var list= document.getElementsByClassName("events");
for (var i = 0; i < list.length; i++) {
console.log(list[i].id); //second console output
}
Explanation For Why You Should Not Use for/in
(为什么不应该for/in
使用的解释)
for/in
is meant for iterating the properties of an object.(for/in
用于迭代对象的属性。)
That means it will return all iterable properties of an object.(这意味着它将返回对象的所有可迭代属性。) While it may appear to work for an array (returning array elements or pseudo-array elements), it can also return other properties of the object that are not what you are expecting from the array-like elements.(尽管它似乎可以用于数组(返回数组元素或伪数组元素),但它也可以返回对象的其他属性,这些属性不是您希望从类似数组的元素中获得的。) And, guess what, an HTMLCollection
or nodeList
object can both have other properties that will be returned with a for/in
iteration.(而且,猜想是什么, HTMLCollection
或nodeList
对象都可以具有其他属性,这些属性将通过for/in
迭代返回。) I just tried this in Chrome and iterating it the way you were iterating it will retrieve the items in the list (indexes 0, 1, 2, etc...), but also will retrieve the length
and item
properties.(我只是在Chrome中尝试了此操作,然后以您迭代的方式对其进行了迭代,它将检索列表中的项目(索引0、1、2等...),但还将检索length
和item
属性。) The for/in
iteration simply won't work for an HTMLCollection.(for/in
迭代对于HTMLCollection根本不起作用。)
See http://jsfiddle.net/jfriend00/FzZ2H/ for why you can't iterate an HTMLCollection with for/in
.(有关为什么无法使用for/in
迭代HTMLCollection的信息,请参见http://jsfiddle.net/jfriend00/FzZ2H/ 。)
In Firefox, your for/in
iteration would return these items (all the iterable properties of the object):(在Firefox中, for/in
迭代将返回以下项(对象的所有可迭代属性):)
0
1
2
item
namedItem
@@iterator
length
Hopefully, now you can see why you want to use for (var i = 0; i < list.length; i++)
instead so you just get 0
, 1
and 2
in your iteration.(我们希望,现在你可以看到为什么要使用for (var i = 0; i < list.length; i++)
代替你只会得到0
, 1
和2
中的迭代。)
Following below is an evolution of how browsers have evolved through the time period 2015-2018 giving you additional ways to iterate.(以下是浏览器在2015-2018年期间的演变方式的演变,为您提供了其他迭代方式。)
None of these are now needed in modern browsers since you can use the options described above.(由于您可以使用上述选项,因此现代浏览器现在不需要这些。)
Update for ES6 in 2015(2015年ES6更新)
Added to ES6 is Array.from()
that will convert an array-like structure to an actual array.(ES6中添加了Array.from()
,它将把类似数组的结构转换为实际数组。)
That allows one to enumerate a list directly like this:(这样就可以像这样直接枚举列表:)
"use strict";
Array.from(document.getElementsByClassName("events")).forEach(function(item) {
console.log(item.id);
});
Working demo (in Firefox, Chrome, and Edge as of April 2016): https://jsfiddle.net/jfriend00/8ar4xn2s/(工作演示(截至2016年4月在Firefox,Chrome和Edge中): https : //jsfiddle.net/jfriend00/8ar4xn2s/)
Update for ES6 in 2016(2016年ES6更新)
You can now use the ES6 for/of construct with a NodeList
and an HTMLCollection
by just adding this to your code:(现在,只需将ES6 for / of构造添加到代码中,即可将其与NodeList
和HTMLCollection
使用:)
NodeList.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
HTMLCollection.prototype[Symbol.iterator] = Array.prototype[Symbol.iterator];
Then, you can do:(然后,您可以执行以下操作:)
var list = document.getElementsByClassName("events");
for (var item of list) {
console.log(item.id);
}
This works in the current version of Chrome, Firefox, and Edge.(在当前版本的Chrome,Firefox和Edge中有效。)
This works because it attaches the Array iterator to both the NodeList and HTMLCollection prototypes so that when for/of iterates them, it uses the Array iterator to iterate them.(之所以行之有效,是因为它将Array迭代器附加到NodeList和HTMLCollection原型上,以便当for / of对其进行迭代时,它使用Array迭代器对其进行迭代。)
Working demo: http://jsfiddle.net/jfriend00/joy06u4e/ .(工作演示: http : //jsfiddle.net/jfriend00/joy06u4e/ 。)
Second Update for ES6 in Dec 2016(ES6的第二次更新于2016年12月)
As of Dec 2016, Symbol.iterator
support has been built-in to Chrome v54 and Firefox v50 so the code below works by itself.(截至2016年12月,Chrome v54和Firefox v50内置了Symbol.iterator
支持,因此以下代码可独立运行。)
It is not yet built-in for Edge.(Edge尚未内置。)
var list = document.getElementsByClassName("events");
for (let item of list) {
console.log(item.id);
}
Working demo (in Chrome and Firefox): http://jsfiddle.net/jfriend00/3ddpz8sp/(工作演示(在Chrome和Firefox中): http : //jsfiddle.net/jfriend00/3ddpz8sp/)
Third Update for ES6 in Dec 2017(ES6的第三次更新(2017年12月))
As of Dec. 2017, this capability works in Edge 41.16299.15.0 for a nodeList
as in document.querySelectorAll()
, but not an HTMLCollection
as in document.getElementsByClassName()
so you have to manually assign the iterator to use it in Edge for an HTMLCollection
.(截至2017年12月,此功能在Edge 41.16299.15.0中可用于document.querySelectorAll()
的nodeList
,但不适用于document.getElementsByClassName()
的HTMLCollection
,因此您必须手动分配迭代器才能在Edge中使用一个HTMLCollection
。)
It is a total mystery why they'd fix one collection type, but not the other.(为什么要修复一种收集类型而不解决另一种收集类型,这完全是个谜。) But, you can at least use the result of document.querySelectorAll()
with ES6 for/of
syntax in current versions of Edge now.(但是,现在至少可以在当前版本的Edge中将带有ES6的document.querySelectorAll()
结果for/of
语法。)
I've also updated the above jsFiddle so it tests both HTMLCollection
and nodeList
separately and captures the output in the jsFiddle itself.(我还更新了上面的jsFiddle,因此它分别测试了HTMLCollection
和nodeList
并捕获了jsFiddle本身的输出。)
Fourth Update for ES6 in Mar 2018(ES6的第四次更新于2018年3月)
Per mesqueeeb, Symbol.iterator
support has been built-in to Safari too, so you can use for (let item of list)
for either document.getElementsByClassName()
or document.querySelectorAll()
.(对于每个中队, Symbol.iterator
支持也已内置到Safari中,因此您可以将document.getElementsByClassName()
或document.querySelectorAll()
for (let item of list)
document.querySelectorAll()
。)
Fifth Update for ES6 in Apr 2018(ES6的第五次更新于2018年4月)
Apparently, support for iterating an HTMLCollection
with for/of
will be coming to Edge 18 in Fall 2018.(显然,对for/of
迭代HTMLCollection
支持将在2018年秋季的Edge 18中提供。)
Sixth Update for ES6 in Nov 2018(ES6的第六次更新于2018年11月)
I can confirm that with Microsoft Edge v18 (that is included in the Fall 2018 Windows Update), you can now iterate both an HTMLCollection and a NodeList with for/of in Edge.(我可以确认使用Microsoft Edge v18(包含在2018年秋季的Windows Update中)现在可以在Edge中使用for / of迭代HTMLCollection和NodeList。)
So, now all modern browsers contain native support for for/of
iteration of both the HTMLCollection and NodeList objects.(因此,现在所有现代浏览器都原生支持HTMLCollection和NodeList对象的for/of
迭代。)