2011-09-25 63 views
0

可能重复:
Javascript - this Vs. prototypeJavaScript的原型混乱

This article说,原型对象也可以帮助你快速添加自定义的方法是体现在它的所有实例的对象。

但这个代码(不使用原型对象)还增加了方法的所有实例:

function al(){ 
    this.show = function(){alert('hi!')} 

} 

var x = new al(); 
x.show(); 

var y = new al(); 
y.show(); 

可能是什么原型对象这里的优势在哪里?我误读了那篇文章吗?

回答

1

主要问题是内存使用情况。你的第一个代码示例将为你的类的每个实例创建一个函数'show'的新副本。如果使用原型方法,则在所有实例之间共享一个函数副本。然后使用函数中的'this'运算符访问正在编辑的实例。

对于两三个实例,这可能并不重要,但是如果可能有数百或数千个实例,它们中的每个实例都具有不同的函数副本,将会对应用程序的性能产生巨大影响。

4

这里的区别在于您将方法show添加到al的实例中而不是原型。添加到原型效果中的所有实例al同时添加到实例只影响该实例。

下面是一个示例,增加了show原型与实例

function al() { 

} 

al.prototype.show = function() { alert("hi"); }; 

这里的关键是,现在的al每个实例都将有机会获得其连接到原型show的单个实例。更厉害的是通过原型

var x = new al(); 
console.log(x.Prop); // x.Prop === undefined 
al.prototype.Prop = 42; 
console.log(x.Prop); // x.Prop === 42 
+0

+1,非常好的解释。 –

+0

但我不能通过原型添加,我可以编辑构造函数定义(例如this.Prop = 42在函数al()中)原型对象的优点是什么呢?本克莱顿只说内存使用? – DrStrangeLove

+0

@DrStrangeLove:一个更好的例子就是创建一个实例,然后更改原型。您会看到之前创建的对象也具有新属性。所以通过扩展原型可以扩展已经创建的实例。 –

0

是不同的是,当你做你的方式,每一个al实例都有其自己的show方法的副本,以增加现有对象的能力。

如果你把它放在原型上,所有实例共享该方法的一个副本,并在调用该方法时为你应用上下文(即范围)。将该方法放在原型上效率更高。

0

这意味着如果你想在定义后添加一个成员函数或变量到al - 特别是如果al是由其他人定义的。如果你不知道的原型做到了,你可以尝试以下操作:

function al(){ 
    this.show = function(){alert('hi!')} 

} 

al.newfunction = function(){alert('hello!')} 

var x = new al(); 
x.show(); 
// THIS WILL FAIL 
x.newfunction(); 

相反,你需要说:

al.prototype.newfunction = function(){alert('hello!')} 

var x = new al(); 
x.show(); 
// THIS WILL SUCCEED 
x.newfunction(); 
0

您已经定义了show方法decalred为al的一部分目的。 prototype可以让你免除现有的课程。下面是一个例子,它会为字符串对象添加一个'trim'函数。一旦将函数添加到代码中,“修剪”功能将可用于字符串对象的所有实例

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }; 
0

请参见此示例。

<script> 
    function al(){ 
    this.show = function(){alert('hi!')} 
    } 

    var x = new al(); 
    x.show(); 

    var y = new al(); 
    y.show(); 
    y.test = function(){alert('no prototype!')}; 
    y.test(); 
    //x.test(); // error 

    al.prototype.test2 = function(){alert('prototype!')}; // edit al prototype 
    y.test2(); // no error 
    x.test2(); // no error 
</script>