Array.prototype.slice.call()如何工作?

我知道它用于使参数成为一个真正的数组,但我不明白使用Array.prototype.slice.call(arguments)时会发生什么情况。


在引擎盖下发生的是,当.slice()被正常调用时, this是一个数组,然后它只是迭代该数组,并完成它的工作。

如何为this.slice()函数对数组? 因为当你这样做时:

object.method();

...的object自动成为的值thismethod() 所以:

[1,2,3].slice()

...的[1,2,3]数组被设置为的值this.slice()


但是如果你可以用别的东西替代this值呢? 只要你替换的数值有.length属性,以及一些属于数字索引的属性,它就可以工作。 这种类型的对象通常被称为类似数组的对象。

.call().apply()方法让你手动设置的值, this在一个函数。 因此,如果我们的值设置this.slice()到一个数组类的对象, .slice()将只是假设它的工作与Array,并会做它的东西。

以这个普通对象为例。

var my_object = {
    '0': 'zero',
    '1': 'one',
    '2': 'two',
    '3': 'three',
    '4': 'four',
    length: 5
};

这显然不是一个数组,但是如果你可以将它设置为.slice()this值,那么它就可以工作,因为它看起来就像一个数组,用于.slice()正常工作。

var sliced = Array.prototype.slice.call( my_object, 3 );

例如: http : //jsfiddle.net/wSvkv/

正如你在控制台中看到的那样,结果就是我们所期望的:

['three','four'];

所以当你将arguments对象设置为.slice()this值时,会发生这种情况。 因为arguments有一个.length属性和一堆数字索引, .slice()只是像工作在一个真实的数组上一样。


arguments对象实际上不是数组的一个实例,也没有任何数组方法。 所以, arguments.slice(...)将不起作用,因为arguments对象没有slice方法。

数组确实有这种方法,并且因为arguments对象与数组非常相似,所以两者是兼容的。 这意味着我们可以使用参数对象的数组方法。 由于数组方法是在数组的基础上构建的,因此它们将返回数组而不是其他参数对象。

那么为什么要使用Array.prototypeArray是我们从( new Array() )创建新数组的对象,并且这些新数组通过方法和属性(如slice)传递。 这些方法存储在[Class].prototype对象中。 所以,为了提高效率,我们不是通过(new Array()).slice.call()[].slice.call()来访问slice方法,而是直接从原型中获取它。 这样我们就不必初始化一个新的数组了。

但为什么我们首先要做到这一点? 那么,如你所说,它将一个参数对象转换为一个数组实例。 然而,我们使用分片的原因更多的是“黑客”。 切片方法将采取,你猜对了,切片数组并返回该切片作为一个新的数组。 除了参数对象作为其上下文之外,不传递任何参数(除了参数对象作为其上下文)都会导致切片方法获取传递的“数组”(本例中为参数对象)的完整块并将其作为新数组返回。


通常,打电话

var b = a.slice();

将数组a复制到b 。 但是,我们做不到

var a = arguments.slice();

因为arguments不是真正的数组,并且没有slice作为方法。 Array.prototype.slice是数组的slice函数,并且call this arguments设置为arguments来运行该函数。

链接地址: http://www.djcxy.com/p/72257.html

上一篇: how does Array.prototype.slice.call() work?

下一篇: Why was ECMAScript 4th edition completely scrapped?