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

时间:2012-12-16 11:18:52

标签: javascript

  

可能重复:
  Why is it Object.defineProperty() rather than this.defineProperty() (for objects)?

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

var a = ['one', 2, 3, 'four'];
a.reverse();
// OR
Array.reverse(a);

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

1 个答案:

答案 0 :(得分:6)

对于名为Object.method(o)的属性,

Object查看Object对象(method是JavaScript中的真实对象),并尝试通过变量{{传递它来调用它1}}。在通话过程中,o将为this

Object查看变量o.method()引用的对象,查找名为o的属性并尝试调用它,而不是传递任何内容。在调用期间,method将是this

正如你所看到的,他们做了很多不同的事情。

  

我注意到特定对象的所有方法都可以从实际的对象实例中调用...或者通过将对象作为参数传递给o

不,他们不能。您的示例Object.method()Array.reverse(a)的标准实现上失败,因为Array没有名为Array的属性,因此无法将其作为函数调用。 修改:您在评论中注意到它在Firefox的暂存器中有效,我刚刚验证了这一点。这意味着Firefox的SpiderMonkey JavaScript引擎正在向reverse应用非标准扩展,它提供Array的静态实现。这是Firefox的reverse特有的,不是所有对象的通用。 (例如,如果您创建自己的Array,其原型函数也不会神奇地添加到Foo。)

标准使近似等效于Foo的方法将通过原型,如下所示:

a.reverse()

在标准引擎中工作。那么让我们来看看它的作用:

  1. 它从Array.prototype.reverse.call(a); 获取prototype属性。

  2. 它从#1中获得的对象中获取Array属性。

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

  4. 创建数组时,该对象将获得基础原型。该原型是创建新数组时call引用的对象。因此Array.prototype具有a属性,因为其基础原型具有reverse属性。

    执行reverse会这样做:

    1. a.reverse()对象获取reverse属性。由于(通常)a将没有自己的属性a,因此标准JavaScript属性查找会查找reverse的基础原型。它在那里找到属性并使用它的值。

    2. 调用此功能,使a在通话中为this

    3. 如您所见,最终结果与提供的相同,aa的基础原型仍然引用同一个对象。 (虽然在Array.prototype或任何其他内置的情况下,如果某人被替换 [而不是扩充] {{ 1}},那将是一件坏事(tm)。)