ChatGPT解决这个技术问题 Extra ChatGPT

forEach 不是 JavaScript 数组的函数错误

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

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

但我收到以下错误:

VM384:53 未捕获的类型错误:parent.children.forEach 不是函数

即使 parent.children 记录:

https://i.stack.imgur.com/cjUUW.png

可能是什么问题呢?

注意:这是一个 JSFiddle

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

D
Dmitri Pavlutin

第一种选择:间接调用 forEach

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

const parent = this.el.parentElement;

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

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

它包含长度属性,表示节点的数量

每个节点都是一个具有数字名称的属性值,从 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() 会起作用
J
Josh Wood

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)); 并且它有效
R
RBT

一个更天真的版本,至少你确定它可以在所有设备上工作,无需转换和 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 怪异。它简单,没有时髦的东西
R
Rajaprabhu Aravindasamy

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

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

不,parent.children 不返回 nodeList 而是返回 HTML 集合。不是一回事。如果它是一个 nodeList,.forEach 可以工作
D
Dmitriy

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 是一种鸭子类型语言。只需使用此功能。
A
Abdelsalam Megahed

您可以检查您是否正确键入了 forEach,如果您像在其他编程语言中一样键入了 foreach,它将无法正常工作。


tldr:函数区分大小写
A
Armfoot

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

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


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

如果您尝试像这样循环 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 ......
A
Ammar Hasan

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

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

不,它不是 NodeList,它是一个 HTML 集合
A
Armfoot

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

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


赞成。多么扭曲,ES6 语法,虽然......让我想哭,而且我来自 C++ 背景......
k
kometen

使用 JSON.parse()

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

您的答案可以通过额外的支持信息得到改进。请edit添加更多详细信息,例如建议的代码是正确解决方案的原因
S
Syed

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

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

或使用扩展运算符:

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