在nodeList上调用forEach

Mon*_*ffy 9 javascript arrays foreach nodelist

我正在使用forEach循环遍历nodeList.我的代码如下

var array = document.querySelectorAll('items');

array.forEach(function (item) {
    console.log(item);
}); 
Run Code Online (Sandbox Code Playgroud)

并且此代码抛出错误

未捕获的TypeError:array.forEach不是函数

然后在阅读了几篇在线博客文章后,我将代码改为此.

[].forEach.call(array, (function (item) {
    console.log(item);
})); 
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么不能在nodeList上调用forEach以及上面的第二个代码片段做了什么.:)

编辑: 7/25/2017

此问题对现代浏览器无效.您可以在其中的节点列表上使用forEach

尽管NodeList不是数组,但可以使用forEach()对其进行迭代.它也可以使用Array.from()转换为Array.

但是,一些较旧的浏览器尚未实现NodeList.forEach()和Array.from().但是使用Array.prototype.forEach()可以避免这些限制(本文档中有更多内容).

参考:MDN

Kub*_*tek 9

这是JavaScript中的一个基本内容:您可以从一个对象获取一个函数并应用于任何其他对象.即:将thisset设置为您应用函数的对象.这是可能的,因为在JavaScript中,所有属性名称等(明确地说)都是通过名称来标识的.因此,尽管NodeList.length存在不同之处,但Array.length该函数Array.forEach可以应用于任何暴露属性length(以及其他forEach需要的东西)的东西.

那么在你的情况下会发生什么:

  • querySelectorAll()返回NodeList类型的对象,它碰巧暴露length属性并且是可枚举的(假设它可以被[]运算符访问); NodeList不公开forEach函数(正如你在这里看到的那样:https://developer.mozilla.org/en-US/docs/Web/API/NodeList) - 这就是为什么不可能forEach直接调用结果querySelectorAll()
  • [].forEach返回一个函数 - 这是一个不那么聪明的快捷方式Array.prototype.forEach
  • [].forEach.call(array, …)被这个函数施加到由所引用的对象array,类型的对象节点列表(即forEach与调用arraythis在功能体,所以,当内部forEachthis.length它指的是lengtharray尽管array节点列表,而不是真正的阵列)
  • 这是有效的,因为forEach使用了ArrayNodeList共有的属性; 它会失败,如果,即forEach想要使用Array拥有的某些属性,但NodeList没有