可能重复:
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);
我似乎得到了同样的行为。我想知道差异是什么,何时会用到另一个?
答案 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()
在标准引擎中工作。那么让我们来看看它的作用:
它从Array.prototype.reverse.call(a);
获取prototype
属性。
它从#1中获得的对象中获取Array
属性。
它调用使用JavaScript函数对象的Function#call
特性引用的属性的函数,使reverse
成为函数调用过程中传递给this
的参数
创建数组时,该对象将获得基础原型。该原型是创建新数组时call
引用的对象。因此Array.prototype
具有a
属性,因为其基础原型具有reverse
属性。
执行reverse
会这样做:
从a.reverse()
对象获取reverse
属性。由于(通常)a
将没有自己的属性a
,因此标准JavaScript属性查找会查找reverse
的基础原型。它在那里找到属性并使用它的值。
调用此功能,使a
在通话中为this
。
如您所见,最终结果与提供的相同,a
和a
的基础原型仍然引用同一个对象。 (虽然在Array.prototype
或任何其他内置的情况下,如果某人被替换 [而不是扩充] {{ 1}},那将是一件坏事(tm)。)