在 javascript 中有两种方法可以将方法添加到对象中,以下方法有什么区别?
1
var o = new Object();
o.method = function(){}
2
var o = new Object();
o.prototype.method = function(){}
在 javascript 中有两种方法可以将方法添加到对象中,以下方法有什么区别?
var o = new Object();
o.method = function(){}
var o = new Object();
o.prototype.method = function(){}
“原型”是全球性的。它可以被所有对象使用。您甚至可以覆盖或删除标准方法。
如果您正在为一个对象定义一个新方法,那么它是本地的并且仅用于该对象的这个实例
另一方面,如果您在原型范围内定义它,那么它的全局和方法是为所有实例定义的
关于原型,您必须首先弄清楚几件事。我在这里写的是一个粗略的概述。还有一些其他的东西涉及到原型是如何工作的,但我试图保持这个简单和基础。
这篇博客文章有一些关于我所说的很好的细节:http: //javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/
只有函数具有 .prototype 属性。实例具有 .constructor 属性。在您的示例中,“o”是 Object 的一个实例。
所有的构造函数都是函数。
根据您使用的浏览器,实例将具有原型属性,例如:
.__proto__
这就是你通常认为的函数的 .prototype 属性。大多数(全部?)版本的 IE 都不在实例上提供“_ _ proto _ _”(用于 SO 格式的额外空格)属性。支持 ECMA5 的浏览器有一个名为 getPrototypeOf() 的方法,它返回实例的原型。
由于构造函数是函数,因此它们具有 .prototype 属性。所以 o.constructor.prototype 是一种以友好的跨浏览器方式访问原型的好方法。对此有一些警告,因为它可以被覆盖。有关更多信息,请参阅博客文章。
所以我们需要做的第一件事是重写你的代码,使语法实际上像我们期望的那样工作。从这一点开始,我将变量名称更改为更清晰:
var foo = new Object(); //a new instance of Object
foo.foo_method = function(){ console.log('foo'); } //add a function called 'foo_method' to our instance
var bar = new Object(); // a new instance of Object
bar.constructor.prototype.bar_method = function(){ console.log('bar'); } //add a function called 'bar_method' to the Object prototype
foo.foo_method(); //logs "foo"
foo.bar_method(); //logs "bar"
bar.bar_method(); //logs "bar"
try{
bar.foo_method();
}catch(err){
console.log(err); //Uncaught TypeError: Object #<Object> has no method 'foo_method' or "TypeError"
}
//Alternate way to add methods to prototypes. Only works in non-IE browsers.
bar.__proto__.woohoo_method = function(){ console.log('woohoo'); }
foo.woohoo_method(); //logs "woohoo"
bar.woohoo_method(); //logs "woohoo"