【问题标题】:Difference between Object.method(o) and o.method() [duplicate]Object.method(o) 和 o.method() 之间的区别 [重复]
【发布时间】:2012-12-16 11:18:51
【问题描述】:

可能重复:
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);

我似乎得到了同样的行为。我想知道有什么区别,什么时候可以使用一个而不是另一个?

【问题讨论】:

标签: javascript


【解决方案1】:

Object.method(o)Object 对象(Object 是 JavaScript 中的真实对象)中查找名为 method 的属性,并尝试通过传入变量 o 来调用它。在通话期间,this 将是Object

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

如您所见,他们做的事情完全不同。

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

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

使a.reverse() 近似等效的标准方法是通过原型,如下所示:

Array.prototype.reverse.call(a);

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

  1. 它从Array获取prototype属性。

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

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

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

a.reverse() 这样做:

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

  2. 调用该函数,使this 在调用中为a

如您所见,最终结果是相同的提供aArray.prototype 的底层原型仍然引用同一个对象。 (他们可能不这样做,尽管在 Array 或任何其他内置的情况下,如果有人 替换 [而不是 augmenting] Array.prototype,那将是一件坏事(tm)。)

【讨论】:

  • Array.reverse(a) 出于某种原因在 Firefox 暂存器中工作(使用 Ctrl+l 输出)。
  • @stariz77: 非常有趣(我已经验证过了)。那将是 Firefox 做一些非标准的事情,我已经更新了答案。
  • @stariz77:顺便说一句,我已经验证了 Firefox 的 Array.reverseArray.prototype.reverse 不会互相调用。我通过首先覆盖Array.prototype.reverse 并注意到Array.reverse 仍然进行反转来证明这一点,然后覆盖Array.reverse 并看到Array.prototype.reverse 仍然进行反转。我希望他们每个人都调用一个内部函数来反转数组。感谢您提供有关 Firefox 的信息,我从来不知道。
猜你喜欢
  • 1970-01-01
  • 2014-07-16
  • 2014-08-16
  • 2011-04-08
  • 2012-11-24
  • 2013-06-05
  • 2021-09-29
  • 2020-05-27
  • 2016-03-23
相关资源
最近更新 更多