【问题标题】:javascript forEach on nodelistjavascript forEach 在节点列表上
【发布时间】:2016-05-30 20:50:14
【问题描述】:

考虑以下代码:

var els = document.querySelectorAll('.myClassName');

Array.prototype.forEach.call(els, function(el) {
  console.log(el.id);
});

var els 包含一个节点列表,它不是数组,forEach 仅适用于数组,对吗? 上面的代码真的是hack吗?

【问题讨论】:

  • 你说nodeList不是数组的定义是什么?它是一个数组。
  • @PawanNogariya:可能是the specification:[NewObject] NodeList querySelectorAll(DOMString selectors);
  • forEach 方法期望变量是类型数组而不是类型 NodeList(如果我错了,请纠正我)。当我在 Chrome 的开发人员工具中查看 Nodelist 时,我发现没有可用的 forEach。

标签: javascript foreach


【解决方案1】:

...并且 forEach 仅适用于数组,对吗?

不。 Array.prototype.forEach 有意通用,它可以应用于任何类数组的对象。来自the spec:

注意 2:forEach 函数是故意通用的;它不要求它的 this 值是一个 Array 对象。因此,它可以转移到其他类型的对象中作为方法使用。

规范清楚地列出了在处理forEach 期间将使用哪些属性和/或方法;只要在调用期间通过this 引用的对象有这些,forEach 就可以在该对象上使用。这就是为什么像这样使用forEach.call 的原因:函数对象上的call 方法(forEach 是一个函数对象)使用您在调用期间将call 作为this 提供的第一个参数调用该函数,并传递以下参数作为原始函数的参数。所以Array.prototype.forEach.call(x, y) 调用forEach 并将this 设置为x 并将第一个参数设置为y。 forEach 不关心this 的类型,只关心它具有规范算法中描述的相关属性和方法。

Array.prototype 的大多数方法都是这样,其他标准原型上的许多其他方法也是如此。


旁注:querySelectorAll 返回的 NodeList 最近在现代浏览器上可迭代,这意味着:1. 它适用于 ES2015+ 的 for-of,以及 2. 它具有 forEach现在本地。 (在现代浏览器上。)

【讨论】:

  • 所以当一个变量真的是一个数组时我可以直接调用forEach,如果不是我使用其他方法?
  • @poashoas:也可以在上面放一个引用forEach函数的属性,直接调用方法。只是数组继承了Array.prototype的函数属性,而其他对象没有。
  • @poashoas:大多数情况下,是的。更准确地说:只要您有一个对象的引用,该对象具有对 Array.prototype.forEach 函数的引用作为属性(直接,或者因为 - 像普通数组一样 - 它从其原型继承),您可以使用forEach 直接就可以了。如果不是,但它是类似数组的,您可以使用call 方法。
  • @Bergi 我正在努力学习 :-D 你如何在 NodeList 上放置一个属性。像 NodeList.prototype.foreach = function() { for(var i = 0; i
  • @T.J.Crowder 这真的很有帮助,我可能会用这个尝试一些东西
猜你喜欢
  • 1970-01-01
  • 2018-07-09
  • 2017-08-24
  • 1970-01-01
  • 1970-01-01
  • 2012-11-01
  • 2011-10-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多