javascript 为什么 forEach 不适用于儿童?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15094886/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why is forEach not working for children?
提问by erik
I have a <div>
with some child <div>
in it. E.g.
我有一个<div>
孩子<div>
在里面。例如
<div id="niceParent">
<div></div>
<div></div>
<div></div>
<div></div>
</div>
I tried to loop through them with the forEach
function, because I thought that document.getElementById("niceParent").children
is an array, as I can access the elements with
我试图用forEach
函数遍历它们,因为我认为这document.getElementById("niceParent").children
是一个数组,因为我可以访问元素
console.log(document.getElementById("niceParent").children[1]);
console.log(document.getElementById("niceParent").children[2]);
console.log(document.getElementById("niceParent").children[3]);
console.log(document.getElementById("niceParent").children[4]);
Hence I tried
因此我试过
document.getElementById("niceParent").children.forEach(function(entry) {
console.log(entry);
});
which is not working. I get
这是行不通的。我得到
TypeError: document.getElementById(...).children.forEach is not a function
As a workaround I also tried it with a—much more complicated—for..in
loop:
作为一种解决方法,我还尝试了一个更复杂的for..in
循环:
for (var i in document.getElementById("niceParent").children) {
if (document.getElementById("niceParent").children[i].nodeType == 1) console.log(document.getElementById("niceParent").children[i]);
}
which worked as expected.
这按预期工作。
Why?
为什么?
回答by Felix Kling
Because .children
contains an HTMLCollection
[MDN], not an array. An HTMLCollection
object is an array-likeobject, which exposes a .length
property and has numeric properties, just likearrays, but it does not inherit from Array.prototype
and thus is not an array.
因为.children
包含HTMLCollection
[MDN],而不是数组。一个HTMLCollection
对象是一个类似数组的对象,它公开了一个.length
属性,并且具有数值属性,只是像阵列,但它不从继承Array.prototype
并且因此不是数组。
You can convert it to an array using Array.prototype.slice
:
您可以使用Array.prototype.slice
以下方法将其转换为数组:
var children = [].slice.call(document.getElementById(...).children);
ECMAScript 6introduces a new API for converting iterators and array-like objects to real arrays: Array.from
[MDN]. Use that if possible since it makes the intent much clearer.
ECMAScript 6引入了一个新的 API,用于将迭代器和类数组对象转换为真正的数组:Array.from
[MDN]。如果可能,请使用它,因为它使意图更加清晰。
var children = Array.from(document.getElementById(...).children);
回答by lonesomeday
Element.children
is notan array. It is an object called an HTMLCollection
. These do not have an array's methods (though they do have the length
property).
Element.children
是不是一个数组。它是一个名为 an 的对象HTMLCollection
。这些没有数组的方法(尽管它们有length
属性)。
To loop through it, you'll have to convert it into an array, which you can do using Array.prototype.slice
:
要循环遍历它,您必须将其转换为一个数组,您可以使用Array.prototype.slice
:
var children = Array.prototype.slice.call(document.getElementById("niceParent").children);
children.forEach(…);
回答by aloisdg moving to codidact.com
A cleaner and more modern way to convert a HTMLCollection
like .children
to an array to use forEach()
(or map()
, etc.) is to use the spread synthax ...
in an array []
.
将HTMLCollection
like转换为.children
要使用的数组forEach()
(或map()
等)的更简洁...
、更现代的方法是在 array 中使用扩展合成器[]
。
var children = [...document.getElementById('x').children];
for example:
例如:
[...document.getElementById('x').children].forEach(child => console.log(child))
This is an es6 feature. It will work on all modern browser.
这是 es6 的特性。它适用于所有现代浏览器。
[...document.getElementById('niceParent').children].forEach(child => console.log(child.textContent))
<div id="niceParent">
<div>a</div>
<div>b</div>
<div>c</div>
<div>d</div>
</div>
回答by Zoltan.Tamasi
You can also do this:
你也可以这样做:
NodeList.prototype.forEach = HTMLCollection.prototype.forEach = Array.prototype.forEach;
And after this you can call forEach on your collection:
在此之后,您可以在您的收藏中调用 forEach:
document.getElementById("niceParent").children.forEach(...)
The best and most secure way would be actually to only add forEach in cases when it doesn't already exist:
最好和最安全的方法实际上是只在不存在的情况下添加 forEach:
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
if (window.HTMLCollection && !HTMLCollection.prototype.forEach) {
HTMLCollection.prototype.forEach = Array.prototype.forEach;
}