我在其他地方看到了这个脚本,它会检查每个复选框:
[].forEach.call(document.querySelectorAll('input[type="checkbox"]'),function(el){
el.checked=true;
}
);
我知道如何使用forEach
:
[0,1,2].forEach(function(num){
console.log(num);
});
//0
//1
//2
但现在,它是[].forEach
,里面什么都没有。那它为什么还能运作呢?为什么我不能这样做呢?
document.querySelectorAll('input[type="checkbox"]').forEach(function(el){
el.checked=true;
}
);
答案 0 :(得分:10)
JavaScript具有一流的功能;也就是说,它们被视为对象,并且可以拥有自己的属性和方法。内置的Function.call
方法将函数的this
参数作为其第一个参数,其余参数将传递给函数本身。除了作为访问(不太简洁,使用较少)[]
方法的方法之外,不使用数组Array.prototype.forEach
。
它基本上是Array.forEach
的重新绑定,用于非数组的东西,在本例中为NodeList
。如果NodeList
提供了forEach
方法,那么它将等同于,您可以将其视为:
document.querySelectorAll('input[type="checkbox"]').forEach(function(el) {
el.checked = true;
});
所以,更深入一点。 call
将执行具有不同上下文的函数。 forEach
遍历上下文并调用它作为参数传递的函数。因此,someFunc.call(thisArg, otherArg)
将像thisArg
一样在thisArg.someFunc(otherArg)
的上下文中执行,就像function callMe(something) {
return something + this;
}
callMe('Hello'); // Hellonull or Hello[object Window] or something
callMe.call({}, 'World'); // World[object Object]
一样。这是最简单的例子:
{{1}}
apply()
的工作方式相同,但你传递一个参数数组作为第二个参数。
答案 1 :(得分:4)
这只是使用[]
来获取forEach
功能。一旦它具有该功能,它就会使用.call
来调用它,就好像它是document.querySelectorAll('input[type="checkbox"]')
的方法一样。
这很有用,因为document.querySelectorAll
的结果不是Array
,但行为与此类似,因此我们可以重复使用标准Array
方法。
使用.call
时,第一个参数用作this
值。也就是说,在此特定代码段中,每次在this
的来源中遇到forEach
时,都会将其设置为document.querySelectorAll('input[type="checkbox"]')
。
您不能直接致电document.querySelectorAll('input[type="checkbox"]').forEach(...
,因为querySelectorAll
不会返回Array
个对象,因此没有forEach
方法。整个.call
事件只是通过调用forEach
来解决此问题的方式,就像它是NodeList
的方法一样,这是实际返回的方法。
答案 2 :(得分:3)
注意.call
。它将this
的结果应用(设置document.querySelectorAll
)到forEach
,以便它迭代这些结果而不是点左侧的(空)数组。