我知道它是用来使参数成为一个真正的数组,但我不明白使用时会发生什么 Array.prototype.slice.call(arguments)
arguments对象实际上不是一个数组的实例,也没有任何数组方法。所以,arguments.slice(...)不会工作,因为参数对象没有切片方法。
数组确实有这种方法,并且因为arguments对象与数组非常相似,所以两者是兼容的。这意味着我们可以使用参数对象的数组方法。而且由于数组方法是用数组构建的,他们将返回数组而不是其他的参数对象。
那为什么要用Array.prototype?这Array是我们从(new Array())中创建新数组的对象,并且这些新数组通过方法和属性(如slice)传递。这些方法存储在[Class].prototype对象中。因此,为了提高效率,而不是通过访问切片的方法(new Array()).slice.call()或[].slice.call(),我们只是从样机把它直。这是因为我们不需要初始化一个新的数组。
但是为什么我们首先要这样做呢?那么,正如你所说,它将一个参数对象转换成一个数组实例。然而,我们使用分片的原因更多的是“黑客”。切片方法会把一个数组切片并将该切片作为一个新数组返回。除了参数对象作为上下文之外,不传递任何参数(除了参数对象作为其上下文)将导致切片方法获取传递的“数组”(本例中为参数对象)的完整块并将其作为新数组返回。
当.slice()正常调用时,this是一个数组,然后它只是迭代该数组,并且完成它的工作。
数组是如何this在.slice()函数中?因为当你这样做时:
object.method();
...该object自动成为价值this的method()。所以:
[1,2,3].slice()
... [1,2,3]Array被设置为thisin 的值.slice()。
但是如果你可以用别的东西来代替this价值呢?只要你替换的数字.length属性和一些属性是数字索引,它应该工作。这种类型的对象通常被称为类似数组的对象。
该.call()和.apply()方法让你手动设置的值this的函数。因此,如果我们将thisin 的值设置.slice()为一个类似数组的对象,.slice()将会假设它正在与一个数组一起工作,并将完成它的工作。
以这个普通对象为例。
var my_object = {
'0': 'zero',
'1': 'one',
'2': 'two',
'3': 'three',
'4': 'four',
length: 5
};
这显然不是一个数组,但是如果你可以将它设置为this值.slice(),那么它就会工作,因为它看起来像一个阵列足够.slice()正常工作。
var sliced = Array.prototype.slice.call( my_object, 3 );
例如: http : //jsfiddle.net/wSvkv/
正如您在控制台中看到的那样,结果就是我们所期望的:
['three','four'];
所以当你将一个arguments对象设置为this值时,会发生这种情况.slice()。因为arguments有一个.length属性和一堆数字索引,.slice()就像在一个真正的数组上工作一样。