2011-09-25 60 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>