我使用forEach循环遍历nodeList。我的代码如下
var array = document.querySelectorAll('items');
array.forEach(function (item) {
console.log(item);
});
此代码抛出错误
未捕获的TypeError:array.forEach不是函数
然后在阅读了几篇在线博客文章后,我将代码改为此。
[].forEach.call(array, (function (item) {
console.log(item);
}));
有人可以解释为什么不能在nodeList上调用forEach以及上面的第二个代码片做了什么。 :)
修改: 7/25/2017
此问题对现代浏览器无效。您可以在其中的节点列表中使用forEach
虽然NodeList不是数组,但可以迭代它 使用forEach()。它也可以使用转换为数组 Array.from()。
然而,一些较旧的浏览器尚未实现 NodeList.forEach()和Array.from()。但这些限制可以 通过使用Array.prototype.forEach()来规避(更多内容 文件)。
参考:MDN
答案 0 :(得分:9)
这是JavaScript中的一个基本内容:您可以从一个对象获取一个函数,并将 apply 应用于任何其他对象。即:将this
设置为您应用该函数的对象来调用它。这是可能的,因为在JavaScript中,所有属性名称等(明确地说)都是通过名称来标识的。因此,尽管NodeList.length
与Array.length
不同,但Array.forEach
函数可以应用到任何公开属性length
的东西(和forEach
的其他内容1}}要求)。
那么在你的情况下会发生什么:
querySelectorAll()
返回 NodeList 类型的对象,该对象恰好公开length
属性并且是可枚举的(让我们说{{1}可以访问它} operator); NodeList 不会公开[]
函数(正如您所见:https://developer.mozilla.org/en-US/docs/Web/API/NodeList) - 这就是为什么它无法调用forEach
}直接在forEach
querySelectorAll()
返回一个函数 - 这是{em>不那么聪明的 [].forEach
Array.prototype.forEach
此函数应用到由[].forEach.call(array, …)
引用的对象上,该对象类型为 NodeList (即{{1}在函数体中调用array
作为forEach
,因此当array
内this
时forEach
引用this.length
length
尽管array
{1}} NodeList 而不是真正的数组)array
正在使用 Array 和 NodeList 共有的属性;如果forEach
想要使用 Array 具有的某些属性,但 NodeList 没有答案 1 :(得分:4)
NodeList
对象不包含方法forEach
,它是Array object的方法。以下代码:
[].forEach.call(array, (function (item) {
console.log(item);
}));
正在使用数组中的forEach
方法并将其传递给NodeList
。
您拥有的另一个选项,也就是说更好,可以将您的NodeList
转换为数组,如下所示:
var myArrayOfNodes = [].slice.call(NodeList);
这使用Array对象slice
method从NodeList
创建节点数组。这是一个更好的方法,因为你可以使用数组而不是黑客攻击类似数组的对象
答案 2 :(得分:-1)
querySelectorAll
获取array-like
对象中的元素而不是数组。所以你需要在第二个代码示例中使用它。