forEach不是JavaScript数组的函数错误

时间:2016-03-13 12:03:31

标签: javascript ecmascript-6 vue.js

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

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

但是我收到以下错误:

  

VM384:53未捕获的TypeError:parent.children.forEach不是函数

即使parent.children记录:

enter image description here

可能是什么问题?

注意:这是JSFiddle

12 个答案:

答案 0 :(得分:73)

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

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

parent.childrenNodeList类型,它类似于数组,因为:

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

this article中查看更多详情。

答案 1 :(得分:61)

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

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

或使用传播运营商:

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

答案 2 :(得分:11)

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

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

答案 3 :(得分:8)

更多天真版本,至少您确定它可以在所有设备上运行,无需转换和ES6:

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

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

答案 4 :(得分:6)

parent.childrenHTMLCollection,它是类似于数组的对象。首先,您必须将其转换为真实的Array才能使用Array.prototype方法。

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

答案 5 :(得分:6)

那是因为parent.childrenNodeList,并且它不支持.forEach方法(因为NodeList是一个类似结构的数组而不是数组),所以试着调用它首先使用

将其转换为数组
var children = [].slice.call(parent.children);
children.forEach(yourFunc);

答案 6 :(得分:3)

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

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

答案 7 :(得分:3)

如果你试图像这样循环NodeList

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

我强烈建议以这种方式循环:

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

就我个人而言,我尝试了几种方法,但大多数方法并没有工作,因为我想绕过NodeList,但这个就像魅力一样,试一试!< / p>

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

需要有关NodeList的更多信息?请阅读documentation on MDN

答案 8 :(得分:2)

由于您使用的是ES6(arrow functions)的功能,因此您也可以像这样使用for loop

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
</head>
<body ng-app="app" ng-controller="appCtrl as vm" >
<script src="https://rawgit.com/angular/bower-angular/master/angular.min.js"></script>
  <button ng-click="vm.add()">Add New Cell</button>
  <div ng-repeat="item in vm.list"  >
    <element selected="item == vm.selected"  ng-click="vm.selected = item"></element>
  </div>
  Selected Element : {{vm.selected}}
</body>
</html>

答案 9 :(得分:1)

您可以检查是否正确键入了 forEach ,是否像其他编程语言一样键入了 foreach

答案 10 :(得分:0)

这一直对我有用

const someElement = document.querySelectorAll('.someElement');

  someElement.forEach((element) => {
    // Your code here
  });

答案 11 :(得分:0)

您可以使用childNodes代替children,考虑到浏览器兼容性问题,childNodes也更可靠,更多信息here

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

或使用传播运算符:

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