【问题标题】:forEach is not a function error with JavaScript arrayforEach 不是 JavaScript 数组的函数错误
【发布时间】:2016-06-28 10:54:35
【问题描述】:

我正在尝试做一个简单的循环:

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

但我收到以下错误:

VM384:53 Uncaught TypeError: parent.children.forEach 不是函数

即使parent.children 记录:

可能是什么问题?

注意:这是JSFiddle

【问题讨论】:

  • element.siblings 出现同样的问题
  • @Daut 是,因为 element.siblings 返回一个 HTMLCollection 而 HTMLCollections 没有 forEach() 方法
  • 你好,谷歌搜索器!如果您正在阅读这篇文章,请仔细检查它是否是带有大写 E 而不是 foreach 的 forEach ....

标签: javascript ecmascript-6 vue.js


【解决方案1】:

第一个选项:间接调用 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, ...}

this article查看更多详情。


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

parent.children 是一个HTMLCollection: 它实现了iterable protocol。在 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);
}

【讨论】:

  • 当我使用您的解决方案时,我没有更多问题,但是匿名函数内的代码没有执行。 ..所以..
  • 您使用哪个浏览器,以便 parent.children 告诉您它是一个 nodeList。在 Firefox 上,它告诉我是一个 HTMLCollection。如果它是一个 nodeList,.forEach() 可以工作
【解决方案2】:

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

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

或使用扩展运算符:

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

【讨论】:

  • 我更喜欢这个解决方案,而不是弄乱 Array 原型。
  • 这个答案是 OPs 问题的正确答案之一。 parent.children 是一个没有 .forEach 方法的 HTMLCollection
  • 我在我的案例中使用了Array.from(selected_rows).forEach(item => console.log(item));,它可以工作
【解决方案3】:

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

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

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

【讨论】:

  • 赞成,因为所有这些新的 ES6 函数都与可用的旧功能完全相同,但以一种混乱的方式,与 JS 一样
  • 这是更好的解决方案。它与其他编程语言很接近,并且不太可能出现奇怪的 JS 怪异现象。它简单,没有时髦的东西
【解决方案4】:

parent.children 将返回一个 node list 列表,技术上是一个html Collection。那是一个类似对象的数组,但不是数组,所以你不能直接在它上面调用数组函数。在这种情况下,您可以使用Array.from() 将其转换为真正的数组,

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

【讨论】:

  • 不,parent.children 不返回 nodeList 而是返回一个 HTML 集合。不是一回事。如果它是一个 nodeList,.forEach 可以工作
【解决方案5】:

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

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

【讨论】:

  • 或者不转换,而是在.forEach()上使用.call()?
  • @nnnnnn 请参阅下面的答案。
  • 有很多方法可以将类数组对象转换为数组 :) 这是其中之一
  • @DmitriyLoskutov 你不需要转换它 - JavaScript 是一种鸭子类型的语言。只需使用此功能。
【解决方案6】:

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

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

【讨论】:

  • 不幸的是 parent.children 不是 nodeList... .from() 不起作用。
  • @Cedric 如果您的对象不是 NodeList,那么您应该提出一个专门解决它的新问题。在这里,当答案本质上是错误或有害时使用降级投票,正如您在代码 sn-p 中看到的那样,对象的所有元素都被迭代和打印,这是 OP 问题的目标。
  • 是的,问题在于 OP 的问题与 HTML 集合有关,而不是 nodeList...所以答案根本就是没有回答问题
  • @Cedric 这个答案还将遍历 HTML 集合,因为Array.from 将第一个参数中给出的对象转换为数组。结果与madox2's answer 中的结果相同,无需额外的forEach 循环(Array.from MDN 文档)。
【解决方案7】:

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

【讨论】:

  • tldr:函数区分大小写
【解决方案8】:

如果您尝试像这样循环 NodeList

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

我强烈推荐这样循环:

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

就我个人而言,我尝试了几种方法,但大多数都不起作用,因为我想遍历 NodeList,但这个方法就像一个魅力,试一试!

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

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

【讨论】:

  • 这个答案显然适用于nodeList。问题是 parent.children 返回一个 HTML 集合,它不是 nodeList...
【解决方案9】:

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

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

【讨论】:

  • 不,它不是 NodeList,它是一个 HTML 集合
【解决方案10】:

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

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

【讨论】:

  • 赞成。多么扭曲,ES6 语法,不过……让我想哭,而且我来自 C++ 背景……
【解决方案11】:

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

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

或使用扩展运算符:

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

【讨论】:

    【解决方案12】:

    使用 JSON.parse()

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

    【讨论】:

    • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如建议的代码是正确解决方案的原因
    猜你喜欢
    • 2017-04-06
    • 1970-01-01
    • 2018-03-02
    • 2022-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多