我正在学习Javascript,我很想知道,正在使用原型声明,如下:
function TSomeObj()
{
this.name="my object";
}
TSomeObj.prototype.showname = function() {
alert(this.name);
}
基本上就像这样做:
function TSomeObj()
{
this.name="my object";
this.showname = function() {
alert(this.name);
}
}
当我转储对象的属性时,我得到相同的结果:
TSomeObj (inline version) =
{
'name': 'my object',
'test': function
}
TSomeObj (prototype declaration) =
{
'name': 'my object',
'test': function
}
使用原型声明的好处是什么?除了更少的混乱和更有序的源代码之外。
更新:我或许应该更清楚地表明,这是我感到好奇的最终结果。最终结果是相同的(即在对象原型中都注册了一个新函数) - 但它们的方式却截然不同。感谢您的回复和信息!
答案 0 :(得分:21)
答案 1 :(得分:7)
接受的答案错过了原型和绑定到特定对象的方法之间最重要的区别,所以我要澄清
原型函数只被声明一次。使用
附加的功能this.method = function(){}
每当您创建类的实例时,都会一次又一次地重新声明。因此,原型通常是将函数附加到类的首选方法,因为它们使用较少的内存,因为该类的每个实例都使用相同的函数。然而,正如Erik指出的那样,使用原型附加到附加到特定对象的函数具有不同的范围,因此原型无法访问函数构造函数中定义的“私有”变量。
至于原型 实际上 是什么,因为它是来自传统OO语言的奇怪概念:
每当您创建函数的新实例时:
var obj = new Foo();
运行以下逻辑(不是字面上的代码,但类似的东西):
var inheritsFrom = Foo,
objectInstance = {};
objectInstance.__proto__ = inheritsFrom.prototype;
inheritsFrom.apply( objectInstance, arguments );
return objectInstance;
这样:
{}
,以表示函数的新实例__proto__
。请注意,这是一个引用副本,因此Foo.prototype
和objectInstance.__proto__
现在引用 相同的 对象,并且在一个对象中进行的更改可以是立即见到了另一个。this
来调用该函数
并且每当您尝试访问函数或属性时,例如:obj.bar()
,都会运行以下逻辑:
if( obj.hasOwnProperty('bar') ) {
// use obj.bar
} else if( obj.__proto__ ){
var proto = obj.__proto__;
while(proto){
if( proto.hasOwnProperty('bar') ){
// use proto.bar;
}
proto = proto.__proto__;
}
}
换句话说,检查以下内容:
obj.bar
obj.__proto__.bar
obj.__proto__.__proto__.bar
obj.__proto__.__proto__.__proto__.bar
... etc
直到__proto__
最终等于null
,因为您已到达原型链的末尾。
许多浏览器现在实际公开__proto__
,因此您可以在Firebug或Chrome / Safari中的控制台中进行检查。 IE没有暴露它(并且内部可能有相同的名称不同的名称)。