在JavaScript中解释[] .slice.call?

时间:2010-01-24 02:48:56

标签: javascript arrays call slice

我偶然发现了将DOM NodeList转换为常规数组的简洁快捷方式,但我必须承认,我并不完全理解它是如何工作的:

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

所以它以空数组[]开头,然后slice用于将call的结果转换为新数组是吗?

我不明白的是call。如何将document.querySelectorAll('a')从NodeList转换为常规数组?

8 个答案:

答案 0 :(得分:142)

这里发生的事情是,您使用slice()NodeList称为call()的函数。在这种情况下slice()做的是创建一个空数组,然后遍历它运行的对象(最初是一个数组,现在是NodeList)并继续将该对象的元素附加到空数组中创建,最终返回。这是一个article on this

修改

  

所以它从空数组[]开始,然后切片用于   将调用结果转换为新数组是吗?

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

答案 1 :(得分:109)

在javascript中,对象的方法可以在运行时绑定到另一个对象。简而言之,javascript允许对象“借用”另一个对象的方法:

object1 = {
    name:'frank',
    greet:function(){
        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正在借用数组的切片方法。转换是什么切片返回另一个数组的结果。

答案 2 :(得分:25)

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

答案 3 :(得分:19)

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

其中一些对象包括:

    函数中的
  • arguments
  • NodeList(记住他们的内容在获取后可能会发生变化!因此将它们转换为数组是一种冻结它们的方法)
  • jQuery集合,又名jQuery对象(某些文档:APItypelearn

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

另请注意,第一个参数0可以省略,thorough explanation here

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

答案 4 :(得分:11)

  

如何转换document.querySelectorAll('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
  • 由于endundefinedthis.length将存储在e
  • 空数组将存储在变量a
  • 完成上述设置后,将发生以下迭代

    while(s < e) {
      a.push(this[s]);
      s++;
    }
    
  • 填充的数组a将作为结果返回。

P.S为了更好地理解我们的场景,我们的上下文所需的一些步骤已被callslice的原始算法忽略。

答案 5 :(得分:5)

[].slice.call(document.querySelectorAll('.slide'));

1. The querySelectorAll() method returns all elements in the document that matches a specified selector(s). 

2. The call() method calls a function with a given this value and arguments provided individually.

3. The slice() method returns the selected elements in an array, as a new array object.

  so this line return the array of [object HTMLDivElement]. Here is the six div with classname "slide" so array length will be 6.

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

<script type="text/javascript">

  var arraylist = [].slice.call(document.querySelectorAll('.slide'));

  alert(arraylist);

</script>

答案 6 :(得分:3)

从ES6开始:只需使用 Array.from(element.children) Array.from({length:5})

制作数组

答案 7 :(得分:0)

这可能也有帮助。

切片方法

说明:

slice不会更改原始数组。它从原始数组返回元素的浅表副本。将原始数组的元素复制到返回的数组中。

slice()方法将数组的一部分的浅表副本返回到从头到尾(不包括end)选择的新数组对象中,其中start和end表示该数组中项的索引。原始数组将不会被修改。 查看更多:Reference/Global_Objects/Array/slice

调用方法

说明:

call()允许分配属于一个对象的函数/方法,并为另一个对象调用该函数/方法。

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

查看更多:Reference/Global_Objects/Function/call