[].slice的解释。调用javascript?

我无意中发现了这个将DOM节点列表转换为常规数组的简洁快捷方式,但我必须承认,我并不完全理解它是如何工作的:

[].slice.call(document.querySelectorAll('a'), 0)

所以它从一个空数组[]开始,然后使用slicecall的结果转换为一个新数组,是吗?

我不理解的位是call。如何将document.querySelectorAll('a')从节点列表转换为常规数组?

91550 次浏览

这里发生的事情是你调用slice(),就好像它是使用call()NodeList的函数一样。在这种情况下,slice()所做的是创建一个空数组,然后遍历它所运行的对象(最初是一个数组,现在是NodeList),并不断将该对象的元素添加到它所创建的空数组中,最终返回该空数组。这是一个关于此的文章

编辑:

所以它以一个空数组开始[],然后slice用于 将调用结果转换为一个新数组?< / p >

这是不对的。[].slice返回一个函数对象。函数对象有一个函数call(),该函数调用将call()的第一个形参赋值给this的函数;换句话说,使函数认为它是从形参(document.querySelectorAll('a')返回的NodeList)而不是从数组调用的。

它从Array中检索slice函数。然后调用该函数,但使用document.querySelectorAll的结果作为this对象,而不是实际的数组。

在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'

函数对象的callapply方法(在JavaScript中,函数也是对象)允许你这样做。在你的代码中,你可以说NodeList借用了一个数组的slice方法。.slice()返回另一个数组作为它的结果,它将成为你可以使用的“转换”数组。

它是一种将类数组对象转换为实际数组的技术。

这些对象包括:

  • arguments在函数中
  • 节点列表(记住它们的内容在被获取后可以改变!所以将它们转换为数组是一种冻结它们的方法)
  • jQuery集合,也就是jQuery对象(一些文档:API类型学习)

这有很多用途,例如对象是通过引用传递的,而数组是通过值传递的。

另外,注意第一个参数0可以省略,详细解释

为了完整起见,还有jQuery.makeArray ()

如何将document.querySelectorAll('a')从a NodeList转换为正则数组?< / p >

这是我们的密码,

[].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

call中调用slice函数的执行

  • start将被赋值给变量s作为0
  • 因为endundefined,所以this.length将存储在e
  • 空数组将存储在变量a
  • 在做出上述设置后,将发生以下迭代

    while(s < e) {
    a.push(this[s]);
    s++;
    }
    
  • the filled up array a will be returned as the result.

P.S For better understanding of our scenario some steps that are necessary for our context has been ignored from the original algorithm of call and slice.

[].slice.call(document.querySelectorAll('.slide'));
  1. querySelectorAll()方法返回文档中与指定选择器匹配的所有元素。

  2. call()方法使用给定的值和单独提供的参数调用函数。

  3. slice()方法返回数组中所选的元素,作为一个新的数组对象。

所以这一行返回数组[object HTMLDivElement]。下面是六个div,类名为“slide”;数组长度是6。

var arraylist = [].slice.call(document.querySelectorAll('.slide'));
console.log(arraylist);
<div class="slideshow">
<div class="slide">
first slider1
</div>
<div class="slide">
first slider2
</div>
<div class="slide">
first slider3
</div>
<div class="slide">
first slider4
</div>
<div class="slide">
first slider5
</div>
<div class="slide">
first slider6
</div>
</div>

简单地用Array.from (element.children)Array.from({长度:5})创建数组

这也可能有所帮助。

片的方法

描述:

Slice不会改变原始数组。它返回原始数组元素的浅拷贝。原始数组的元素被复制到返回的数组中。 slice()方法将数组部分的浅拷贝返回到从开始到结束(end不包括)选择的新数组对象中,其中start和end表示该数组中项目的索引。原始数组将不会被修改。 参考/ Global_Objects /数组/片

调用方法

描述:

call()允许为不同的对象赋值和调用属于一个对象的函数/方法。

call()方法使用给定的值和单独提供的参数调用函数。 Call()将this的新值提供给函数/方法。使用call(),您可以只编写一次方法,然后在另一个对象中继承它,而不必为新对象重写方法

参见参考/ Global_Objects /功能/电话

在21世纪20年代我们使用

[...document.querySelectorAll('.slide')]

当你想要使用映射或过滤器,但不再需要使用forEach时,它很有用,因为forEach现在工作在document.querySelectorAll('.slide')返回的集合上