请考虑以下代码:
var els = document.querySelectorAll('.myClassName');
Array.prototype.forEach.call(els, function(el) {
console.log(el.id);
});
var els
包含一个nodelist,它不是一个数组,而forEach
只适用于数组吗?
以上代码实际上是黑客吗?
答案 0 :(得分:4)
...而forEach仅适用于数组吗?
不。 Array.prototype.forEach
故意通用,它可以应用于 array-like 的任何对象。来自the spec:
注2:
forEach
函数是故意通用的;它不要求它的这个值是一个Array对象。因此,它可以转移到其他类型的对象用作方法。
规范清楚地列出了在处理forEach
期间将使用哪些属性和/或方法;只要在调用期间通过this
引用的对象具有这些对象,就可以在该对象上使用forEach
。这就是使用forEach.call
之类的原因:函数对象上的call
方法(forEach
是一个函数对象)使用你给call
的第一个参数调用函数{{ 1}}在调用期间,并传递以下参数作为原始函数的参数。因此this
调用Array.prototype.forEach.call(x, y)
,forEach
设置为this
,第一个参数设置为x
。 y
并不关心forEach
的类型,只是它具有规范的算法中描述的相关属性和方法。
大多数this
方法都是这样的,其他标准原型确实很多。
附注:Array.prototype
返回的NodeList
最近在现代浏览器上变为 iterable ,这意味着:1。它适用于ES2015 +的querySelectorAll
和2它现在原生for-of
。 (在现代浏览器上。)