27

我正在阅读 John Resig 出色的高级 javascript 教程,但我并不完全理解以下调用之间的区别:(请注意,“参数”是一个内置的 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 的行为不符合预期?(这是返回参数列表中除第一个元素之外的所有元素)。

4

6 回答 6

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 实例(例如 Array() 或 [])的 slice 函数。

Array.slice 甚至根本不为空的事实是对象(/函数/构造函数)本身的错误实现。 尝试在 IE 中运行等效代码,您将收到 Array.slice 为 null 的错误

这就是 Array.slice 行为不正确的原因(String.substring 也不正确)。

证明(根据 slice() 的定义,以下是人们不应该期待的事情......就像上面的 substring() 一样):

>>> Array.slice.call([1,2], [3,4])
3,4

现在,如果您在实例化对象Array 原型上正确调用 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
于 2008-09-23T14:22:51.487 回答
6

Array 只是一个函数,尽管它是一个特殊的函数(用于初始化数组)。Array.slice 是对 Array 原型中 slice() 函数的引用。它只能在数组对象上调用,而不能在构造函数(即数组)本身上调用。Array 似乎表现得特别,因为 Array() 返回一个空数组。这似乎不适用于非内置构造函数(你必须使用新的)。所以

Array().slice.call

是相同的

[].slice.call
于 2008-09-23T13:39:18.330 回答
1

由于未提供上下文参数,因此在提供的示例中对 slice.call() 的任何调用如何工作?slice 是否实现了它自己的 call 方法,从而覆盖了 JavaScript 的 call 方法?call 和 apply 方法将对象作为第一个参数,以指定要应用于调用的上下文 (this) 对象。

于 2009-11-28T20:22:08.053 回答
0

我相信Array是类型,而Array()是构造函数。

FireBug中胡闹:

>>> Array === Array()
false

>>> Array.constructor
Function()

>>> Array().constructor
Array()
于 2008-09-23T13:51:37.723 回答
-1

好,

查看http://www.devguru.com/Technologies/ecmascript/quickref/slice.html

Array().slice 是数组类中的函数(构造函数),不能作为数据成员使用。如果您不想使用“()”,则需要在数组上调用它。即 - arguments.slice(1)

于 2008-09-23T13:42:46.560 回答
-1

我的猜测是 Array 是一个原型,而 Array() 是一个实际的数组对象。根据 JavaScript 解释,直接调用内置对象类型的原型方法可能有效,也可能无效。我不相信规范说它必须工作,只是在实例化对象上调用它是有效的。

于 2008-09-23T13:43:31.673 回答