为什么无法在nodeList上调用forEach? [英] Why it is not possible to call forEach on a nodeList?

查看:159
本文介绍了为什么无法在nodeList上调用forEach?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using a forEach to loop through a nodeList. My code is as follows

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

array.forEach(function (item) {
    console.log(item);
}); 

此代码将引发错误

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

Uncaught TypeError: array.forEach is not a function

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

Then after reading few online blog articles i changed the code to this.

[].forEach.call(array, (function (item) {
    console.log(item);
})); 

有人可以解释一下为什么无法在nodeList上调用forEach以及上面的第二段代码是做什么的.:)

Could someone please explain why it is not possible to call forEach on a nodeList and what does the above second code piece do. :)

修改: 2017年7月25日

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

This question does not valid for modern browsers. You can use forEach on node lists in them

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

Although NodeList is not an Array, it is possible to iterate on it using forEach(). It can also be converted to an Array using Array.from().

但是,某些较旧的浏览器尚未实现NodeList.forEach()或Array.from().但是这些限制可以是通过使用Array.prototype.forEach()规避了(更多内容请参见文档).

However some older browsers have not yet implemented NodeList.forEach() nor Array.from(). But those limitations can be circumvented by using Array.prototype.forEach() (more in this document).

参考: MDN

推荐答案

这是JavaScript中的一项基本工作:您可以将一个函数从一个对象获取,然后 apply 应用于任何其他对象.也就是说:调用 this 并将其设置为应用函数所要应用的对象.这是可能的,因为在JavaScript中,所有属性名称等(显然)都是由名称标识的.因此,尽管 NodeList.length Array.length 有所不同,但函数 Array.forEach 可以应用公开属性 length (以及 forEach 所需的其他内容).

This is a fundamental thing in JavaScript: you can take a function from one object and apply to any other object. That is: call it with this set to the object you apply the function to. It is possible, because in JavaScript all property names etc. are (plainly speaking) identified by name. So despite NodeList.length being something different then Array.length the function Array.forEach can be applied to anything that exposes property length (and other stuff that forEach requires).

所以您的情况是这样的:

So what happens in your case is that:

  • querySelectorAll()返回类型为 NodeList 的对象,该对象恰巧暴露了 length 属性,并且可以枚举(例如,可以通过以下方式访问它) [] 运算符); NodeList 不公开 forEach 函数(如您在此处看到的那样:
  • querySelectorAll() returns an object of type NodeList, which happens to expose length property and is enumerable (let's say it is accessible by [] operator); NodeList does not expose forEach function (as you can see i.e here: https://developer.mozilla.org/en-US/docs/Web/API/NodeList) - that's why it's impossible to call forEach directly on the results of querySelectorAll()
  • [].forEach returns a function - this a not so clever shortcut for Array.prototype.forEach
  • with [].forEach.call(array, …) this function is applied onto an object referenced by array, an object of type NodeList (that is forEach is invoked with array as this in function body, so when inside forEach there is this.length it refers to length in array despite array being NodeList and not real Array)
  • this works, because forEach is using properties that Array and NodeList have in common; it would fail if, i.e. forEach wanted to use some property that Array has, but NodeList has not

这篇关于为什么无法在nodeList上调用forEach?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆