Object.method(o)
在Object
对象(Object
在 JavaScript 中是一个真实的对象)上查找一个被调用的属性method
,并尝试通过传入变量来调用它o
。在通话期间,this
将是Object
。
o.method()
在变量引用的对象上查找被调用o
的属性method
并尝试调用它,而不是传入任何内容。在调用期间,this
将是o
.
正如你所看到的,他们做的事情完全不同。
我注意到一个特定对象的所有方法都可以从实际的对象实例中调用......或者通过将对象Object.method()
作为参数传递给它。
不,他们不能。您的示例Array.reverse(a)
在标准实现上失败,Array
因为Array
没有调用属性reverse
,因此不能将其作为函数调用。编辑:您在评论中注意到它可以在 Firefox 的暂存器中使用,我刚刚验证了这一点。这意味着 Firefox 的 SpiderMonkey JavaScript 引擎正在应用一个非标准扩展,Array
该扩展提供了reverse
. 这是特定于 Firefox 的Array
,而不是通用的所有对象。(例如,如果您自己制作Foo
,它的原型函数也不会神奇地添加到其中Foo
。)
使近似等效的标准a.reverse()
方法是通过原型,如下所示:
Array.prototype.reverse.call(a);
这确实适用于标准引擎。那么让我们看看它的作用:
它prototype
从Array
.
它reverse
从它在#1 中获得的对象获取属性。
它利用 JavaScript 函数对象的特性调用属性引用的Function#call
函数,使其成为函数调用过程中this
传入的参数。call
当您创建一个数组时,该对象将获得一个底层原型。Array.prototype
该原型是创建新数组时引用的对象。所以a
有一个reverse
属性,因为它的底层原型有一个reverse
属性。
这样a.reverse()
做:
reverse
从a
对象中获取属性。由于(通常)a
不会有自己的名为 的属性reverse
,因此标准 JavaScript 属性查找会查找a
的底层原型。它在那里找到属性并使用它的值。
调用该函数,使其this
在a
调用中。
如您所见,只要底层原型仍然引用同一个对象a
,最终结果是相同的。Array.prototype
(他们有可能不这样做,尽管在Array
或任何其他内置的情况下,如果有人替换[而不是扩充] Array.prototype
,那将是一件坏事(tm)。)