我正在通过John Resig的优秀Advanced javascript tutorial而我并不完全理解以下调用之间的区别:(请注意'参数'是一个内置的javascript单词,并不完全是一个数组,因此黑客使用Array.slice而不是简单地调用arguments.slice)
>>> arguments
[3, 1, 2, 3]
>>> Array.slice.call( arguments )
3,1,2,3 0=3 1=1 2=2 3=3
>>> Array.slice.call( arguments, 1 )
[]
>>> Array().slice.call( arguments )
3,1,2,3 0=3 1=1 2=2 3=3
>>> Array().slice.call( arguments, 1 )
1,2,3 0=1 1=2 2=3
基本上我的误解归结为Array.slice和Array()。slice之间的区别。这两者之间究竟有什么区别以及为什么Array.slice.call没有按预期运行? (除了参数列表的第一个元素之外的所有内容)。
答案 0 :(得分:39)
不完全。
观察调用String.substring.call(“foo”,1)和String()时会发生什么.substring.call(“foo”,2):
>>> String.substring.call("foo", 1)
"1"
>>> String().substring.call("foo", 1)
"oo"
Array.slice 既不正确引用附加到Array原型的slice函数,也没有附加到任何实例化Array实例的slice函数(例如Array()或[])。
Array.slice甚至完全是非空的这一事实是对象(/ function / constructor)本身的错误实现。 尝试在IE中运行等效代码,您将收到Array.slice为null的错误。
这就是Array.slice行为不正确的原因(String.substring也没有。)
证明(以下是根据slice()的定义永远不会发生的事情......就像上面的substring()一样):
>>> Array.slice.call([1,2], [3,4])
3,4
现在,如果你在实例化的对象或数组原型上正确调用slice(),你将得到你期望的结果:
>>> Array.prototype.slice.call([4,5], 1)
[5]
>>> Array().slice.call([4,5], 1)
[5]
更多证据......
>>> Array.prototype.slice == Array().slice
true
>>> Array.slice == Array().slice
false
答案 1 :(得分:6)
Array只是一个函数,虽然是一个特殊的函数(用于初始化数组)。 Array.slice是对Array原型中slice()函数的引用。它只能在数组对象上调用,而不能在构造函数(即数组)本身上调用。数组似乎表现得特别,因为Array()返回一个空数组。这对于非内置构造函数似乎不起作用(你必须使用new)。所以
Array().slice.call
与
相同[].slice.call
答案 2 :(得分:1)
如果没有提供上下文参数,那么对所提供的示例中的slice.call()的调用是如何工作的? slice是否实现了它自己的调用方法,从而覆盖了JavaScript的调用方法? call和apply方法将对象的第一个参数作为指定要应用于调用的上下文(this)对象。
答案 3 :(得分:0)
我相信 Array 是类型, Array()是构造函数。
在FireBug中徘徊:
>>> Array === Array()
false
>>> Array.constructor
Function()
>>> Array().constructor
Array()
答案 4 :(得分:-1)
那么,
查看http://www.devguru.com/Technologies/ecmascript/quickref/slice.html
Array()。slice是数组类中的函数(构造函数),它不能用作数据成员。如果你不想使用'()',你需要在数组上调用它。 ie - arguments.slice(1)
答案 5 :(得分:-1)
我的猜测是Array是一个原型,而Array()是一个实际的数组对象。根据JavaScript解释,直接调用内置对象类型的原型方法可能有效,也可能不成功。我不相信规范说它必须工作,只是在实例化的对象上调用它。