Object.method(o)和o.method()之间的区别

bqu*_*i56 3 javascript

可能重复:
为什么是Object.defineProperty()而不是this.defineProperty()(对象)?

我注意到特定对象的所有方法都可以从实际的对象实例中调用,即,object.method();或者通过将对象Object.method()作为参数传递.例如:

var a = ['one', 2, 3, 'four'];
a.reverse();
// OR
Array.reverse(a);
Run Code Online (Sandbox Code Playgroud)

我似乎得到了同样的行为.我想知道差异是什么,什么时候会用到另一个?

T.J*_*der 6

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);
Run Code Online (Sandbox Code Playgroud)

并不在标准的发动机工作.那么让我们来看看它的作用:

  1. 它获得了prototype财产Array.

  2. reverse从#1中获得的对象获取属性.

  3. 它调用使用Function#callJavaScript函数对象的特性引用的属性的函数,使其this成为call函数调用过程中传递的参数.

创建数组时,该对象将获得基础原型.该原型Array.prototype是创建新数组时引用的对象.因此它a有一个reverse属性,因为它的底层原型有一个reverse属性.

这样a.reverse()做:

  1. reversea对象获取属性.由于(通常)a不会调用自己的属性reverse,因此标准JavaScript属性查找会查找a底层原型.它在那里找到属性并使用它的值.

  2. 该功能使得通话thisa通话中.

正如你所看到的,最终的结果是一样的提供是的基本原型aArray.prototype仍指向同一个对象.(对于他们来说,虽然在Array内置或任何其他内置的情况下,如果有人替换 [而不是扩充 ] Array.prototype,这可能是坏事(tm).)