Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/rest/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么不可能在节点列表上调用forEach?_Javascript_Arrays_Foreach_Nodelist - Fatal编程技术网

Javascript 为什么不可能在节点列表上调用forEach?

Javascript 为什么不可能在节点列表上调用forEach?,javascript,arrays,foreach,nodelist,Javascript,Arrays,Foreach,Nodelist,我使用forEach循环遍历节点列表。我的代码如下 var array = document.querySelectorAll('items'); array.forEach(function (item) { console.log(item); }); 这段代码会抛出一个错误 未捕获类型错误:array.forEach不是函数 在阅读了几篇在线博客文章后,我将代码改为这样 [].forEach.call(array, (function (item) { console

我使用forEach循环遍历节点列表。我的代码如下

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

array.forEach(function (item) {
    console.log(item);
}); 
这段代码会抛出一个错误

未捕获类型错误:array.forEach不是函数

在阅读了几篇在线博客文章后,我将代码改为这样

[].forEach.call(array, (function (item) {
    console.log(item);
})); 
有人能解释一下为什么不能在节点列表上调用forEach,以及上面的第二个代码段的作用是什么吗

编辑:2017年7月25日

这个问题对现代浏览器无效。可以对其中的节点列表使用forEach

虽然NodeList不是数组,但可以对其进行迭代 使用forEach()。还可以使用以下命令将其转换为数组: 数组。from()

但是,一些较旧的浏览器尚未实现 NodeList.forEach()或Array.from()。但这些局限性可能是有限的 通过使用Array.prototype.forEach()避免了此问题(本文将详细介绍 文件)


Ref:

节点列表对象不包含方法
forEach
,它是。以下代码:

[].forEach.call(array, (function (item) {
    console.log(item);
})); 
正在使用数组中的
forEach
方法并向其传递
NodeList

还有一个更好的选择是将
节点列表
转换为数组,如下所示:

var myArrayOfNodes = [].slice.call(NodeList);

这将使用数组对象
切片
节点列表
创建节点数组。这是一种更好的方法,因为您可以使用数组,而不是攻击类似数组的对象

querySelectorAll
获取类似数组的对象中的元素,而不是数组。因此,您需要使用第二个代码示例中的函数。

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

因此,在您的案例中发生的情况是:

  • querySelectorAll()
    返回类型为NodeList的对象,该对象恰好公开了
    length
    属性,并且是可枚举的(假设它可由
    []
    运算符访问);NodeList不公开
    forEach
    函数(如您所见,即:)-这就是为什么不可能直接对
    queryselectoral()的结果调用
    forEach
  • [].forEach
    返回一个函数-对于
    数组.prototype.forEach
  • 使用
    [].forEach.call(array,…)
    此函数应用于
    array
    引用的对象,即NodeList类型的对象(也就是说,
    forEach
    在函数体中被
    array
    作为
    this
    调用,所以在
    forEach
    中有
    this.length
    它指的是
    array
    中的
    length
    ,尽管
    array
    是节点列表而不是实数组)
  • 这是可行的,因为
    forEach
    正在使用数组和NodeList共同拥有的属性;如果
    forEach
    想要使用数组拥有的某个属性,而NodeList没有,它将失败

对不起,你的意思是什么?正如你指出的,
querySelectorAll
的返回值不返回
数组
,因此我们不能显式调用
.forEach
。但是,我们可以通过将它传递到
forEach
来避免键入它来完成任务。术语可能不同,但我猜它可能是一个duck键入。检查并尝试此单线节点列表修补程序,您可以在
NodeList
上使用
forEach