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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 23:27:55  来源:igfitidea点击:

Why is forEach not working for children?

javascriptfor-loopforeachparent-child

提问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 forEachfunction, because I thought that document.getElementById("niceParent").childrenis 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..inloop:

作为一种解决方法,我还尝试了一个更复杂的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 .childrencontains an HTMLCollection[MDN], not an array. An HTMLCollectionobject is an array-likeobject, which exposes a .lengthproperty and has numeric properties, just likearrays, but it does not inherit from Array.prototypeand 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.childrenis notan array. It is an object called an HTMLCollection. These do not have an array's methods (though they do have the lengthproperty).

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 HTMLCollectionlike .childrento an array to use forEach()(or map(), etc.) is to use the spread synthax ...in an array [].

HTMLCollectionlike转换为.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;
}