我偶然发现了这个将 DOM NodeList 转换为常规数组的简洁快捷方式,但我必须承认,我并不完全理解它是如何工作的:
[].slice.call(document.querySelectorAll('a'), 0)
所以它以一个空数组开始[]
,然后slice
用于将结果转换call
为一个新数组是吗?
我不明白的一点是call
. 那如何document.querySelectorAll('a')
从 NodeList 转换为常规数组?
我偶然发现了这个将 DOM NodeList 转换为常规数组的简洁快捷方式,但我必须承认,我并不完全理解它是如何工作的:
[].slice.call(document.querySelectorAll('a'), 0)
所以它以一个空数组开始[]
,然后slice
用于将结果转换call
为一个新数组是吗?
我不明白的一点是call
. 那如何document.querySelectorAll('a')
从 NodeList 转换为常规数组?
这里发生的事情是你调用slice()
好像它是一个NodeList
using的函数call()
。什么slice()
做在这种情况下是通过运行它的对象(最初的数组,现在创建一个空数组,然后迭代NodeList
),并保留追加该对象的元素,它创建的空数组,这是最终返回。这是一篇关于此的文章。
编辑:
所以它以一个空数组[]开头,然后切片用于将调用结果转换为新数组是吗?
那是不对的。[].slice
返回一个函数对象。一个函数对象有一个函数call()
,它调用分配给call()
to的第一个参数的函数this
;换句话说,使函数认为它是从参数(由NodeList
返回的document.querySelectorAll('a')
)而不是从数组调用的。
在 JavaScript 中,一个对象的方法可以在运行时绑定到另一个对象。简而言之,javascript 允许一个对象“借用”另一个对象的方法:
object1 = {
name: 'Frank',
greet() {
alert(`Hello ${this.name}`);
}
};
object2 = {
name: 'Andy'
};
// Note that object2 has no greet method,
// but we may "borrow" from object1:
object1.greet.call(object2); // Will show an alert with 'Hello Andy'
函数对象的call
和apply
方法(在 JavaScript 中,函数也是对象)允许您这样做。因此,在您的代码中,您可以说 NodeList 借用了数组的 slice 方法。.slice()
返回另一个数组作为其结果,它将成为您可以使用的“转换后”数组。
它slice
从Array
. 然后它调用该函数,但使用 的结果document.querySelectorAll
作为this
对象而不是实际数组。
那如何
document.querySelectorAll('a')
从 a 转换NodeList
为常规数组?
这是我们拥有的代码,
[].slice.call(document.querySelectorAll('a'), 0)
先拆开看看
[] // Array object
.slice // Accessing the function 'slice' present in the prototype of Array
.call // Accessing the function 'call' present in the prototype of function object(slice)
(document.querySelectorAll('a'),0)
// 'call' can have arguments like, (thisArg, arg1,arg2...n).
// So here we are passing the 'thisArg' as an array like object,
// that is a 'nodeList'. It will be served as 'this' object inside of slice function.
// And finally setting 'start' argument of slice as '0' and leaving the 'end'
// argument as 'undefined'
步骤:1 执行call
函数
call
,除了 之外thisArg
,其余的参数将被附加到一个参数列表中。slice
将通过将其this
值绑定为
thisArg
(类似数组的对象来自document.querySelector
)和参数列表来调用。即]start
包含的参数0
步骤:2 执行slice
内部调用的函数call
start
将被分配给一个变量s
作为0
end
是undefined
,this.length
将被存储在e
a
进行上述设置后,将进行以下迭代
while(s < e) {
a.push(this[s]);
s++;
}
a
将作为结果返回。