forEach不是JavaScript数组的函数错误

我试着做一个简单的循环:

const parent = this.el.parentElement
console.log(parent.children)
parent.children.forEach(child => {
console.log(child)
})

但我得到以下错误:

Uncaught TypeError: parent.children.forEach不是一个函数

即使parent.children记录:

enter image description here

有什么问题吗?

注意:这里是JSFiddle

603179 次浏览

parent.children是一个HTMLCollection类数组对象。首先,你必须将它转换为一个真正的Array来使用Array.prototype方法。

const parent = this.el.parentElement
console.log(parent.children)
[].slice.call(parent.children).forEach(child => {
console.log(child)
})

parent.children不是数组。它是HTMLCollection,它没有forEach方法。您可以先将其转换为数组。例如在ES6中:

Array.from(parent.children).forEach(child => {
console.log(child)
});

或者使用展开运算符:

[...parent.children].forEach(function (child) {
console.log(child)
});

parent.children将返回一个节点列表列表,技术上是html集合。这是一个类似于object的数组,但不是数组,所以你不能直接在它上面调用数组函数。在这个上下文中,你可以使用Array.from()将其转换为一个实数组,

Array.from(parent.children).forEach(child => {
console.log(child)
})

这是因为parent.children是一个节点列表,并且它不支持.forEach方法(因为NodeList是一个类似数组的结构,但不是数组),所以尝试先通过using将其转换为数组来调用它

var children = [].slice.call(parent.children);
children.forEach(yourFunc);

第一个选项:间接调用forEach

parent.children是一个类似数组的对象。请使用以下解决方案:

const parent = this.el.parentElement;


Array.prototype.forEach.call(parent.children, child => {
console.log(child)
});

parent.childrenNodeList类型,这是一个类似数组的对象,因为:

  • 它包含length属性,该属性表示节点数
  • 每个节点都是一个具有数字名称的属性值,从0开始:{0: NodeObject, 1: NodeObject, length: 2, ...}

详见这篇文章


第二个选择:使用可迭代协议

parent.children是一个HTMLCollection:,它实现了iterable协议. parent.children。在ES2015环境中,你可以将HTMLCollection与任何接受可迭代对象的构造一起使用。

HTMLCollection与展开操作符一起使用:

const parent = this.el.parentElement;


[...parent.children].forEach(child => {
console.log(child);
});

或者使用for..of循环(这是我的首选):

const parent = this.el.parentElement;


for (const child of parent.children) {
console.log(child);
}

一个更天真的的版本,至少你确定它可以在所有设备上工作,不需要转换和ES6:

const children = parent.children;
for (var i = 0; i < children.length; i++){
console.log(children[i]);
}

https://jsfiddle.net/swb12kqn/5/

不需要forEach,你可以只使用from的第二个参数进行迭代,如下所示:

let nodeList = [{0: [{'a':1,'b':2},{'c':3}]},{1:[]}]
Array.from(nodeList, child => {
console.log(child)
});

因为你正在使用ES6 (箭头功能)的特性,你也可以像这样简单地使用for循环:

for(let child of [{0: [{'a':1,'b':2},{'c':3}]},{1:[]}]) {
console.log(child)
}

如果你试图像这样循环NodeList:

const allParagraphs = document.querySelectorAll("p");

我强烈推荐这样循环:

Array.prototype.forEach.call(allParagraphs , function(el) {
// Write your code here
})

就我个人而言,我已经尝试了几种方法,但大多数都不起作用,因为我想循环NodeList,但这个方法就像一个咒语,试试看吧!

NodeList不是数组,但我们使用Array.将其视为数组,因此,您需要知道旧的浏览器不支持它!

需要更多关于NodeList的信息?请阅读它的MDN文档

你可以使用childNodes代替children,考虑到浏览器兼容性问题,childNodes也更可靠。

parent.childNodes.forEach(function (child) {
console.log(child)
});

或者使用展开运算符:

[...parent.children].forEach(function (child) {
console.log(child)
});

你可以检查你是否正确输入了forEach,如果你像在其他编程语言中一样输入了foreach,它将不起作用。

使用JSON.parse ()

str_json = JSON.parse(array);
str_json.forEach(function (item, index) {
console.log(item);
});

对于对象,试试这个:

  Object.keys(yourObj).forEach(key => {
console.log(key, yourObj[key]);
});