2009-11-20 152 views
7

什麼是JavaScript類的原型?換句話說,就是什麼是JavaScript中的原型?

Example.prototype.method {} 

Example.method{} 
限定實施例類時

之間的差異?

編輯:對於那些有興趣,我發現了一個很好的解釋(除了下面的回答)這裏類方法和構造方法的區別:http://idhana.com/2009/07/13/constructor-vs-class-methods-in-javascript/

編輯2:完整的答案! http://blog.anselmbradford.com/2009/04/09/object-oriented-javascript-tip-creating-static-methods-instance-methods/

回答

5

不同之處在於您創建靜態方法的後一個示例,如果Example是構造函數,則不會繼承該靜態方法。通過在構造函數的prototype屬性中定義屬性並使用關鍵字new創建對象,新創建的對象將繼承構造函數的原型,從而可以訪問這些方法。

一個例子是在內置的核心構造,如String定義..新創建的字符串有indexOf方法,因爲有一個在String函數構造函數的原型中定義的方法

typeof String.prototype.indexOf // 'function' 

var name = 'John'; 
alert(name.indexOf('J')) // 0 

的下面的代碼創建了一個函數構造函數,我們首先定義一個靜態方法,創建一個對象,找出該對象沒有getName方法,然後我們在原型中定義一個,並發現該對象確實有一個getName方法。

function Name(name) { 
    this.name = name; 
}; 
Name.getName = function(){}; 

var john = new Name(); 
typeof john.getName // undefined 

var john = new Name(); 
Name.prototype.getName = function(){ alert(this.name)}; 
typeof john.getName 

john.constructor.prototype.getName == john.getName // true 

所以要重申,繼承ECMAScript中主要由定義在函數構造的原型的屬性/方法來實現,例如將所有的核心構造諸如日期/數字/字符串具有方法中定義其相應的原型屬性,它允許您在使用new關鍵字創建實例時使用這些方法。

請記住,新創建的對象具有constructor屬性,該屬性指向創建它的構造函數,我們可以直接訪問prototype屬性。我們創建的john對象並不直接擁有getName方法,因爲解釋器無法直接在對象上找到它,而是向上傳遞給構造函數,並在其原型中找到它。

而順便說一句,我們並不需要創建john對象的新實例,正如您在創建初始構造函數後可以定義原型中的屬性的其他答案中指出的那樣,並且所有對象都會繼承那些原型甚至在它們被創建之後。

靜態方法不能依賴於上下文,不能依靠一類的特定實例,可以不依賴於this關鍵字因此這不會是一個靜態方法:

function Name(name) { 
    this.name = name; 
    this.getName = function() { return this.name; } 
}; 

這將是一個靜態方法的例子:

Name.getName = function() {}; 

,但有在做getName靜態的,因爲顧名思義它必須依賴於一個對象實例,以確定name屬性是什麼,你應該有更多的根兒絕對沒有任何意義ic幫助函數像解析函數(如Date.parse)那樣作爲靜態方法並在原型中定義實例方法,因爲它們比在構造函數中定義this.foo = function(){}更有效。

+0

所以當我想要使用Name.getName = function(){}? – sepiroth 2009-11-20 03:21:14

+0

或者更確切地說,我何時可以在不使用原型定義的情況下爲Name類定義方法(以及如何)? – sepiroth 2009-11-20 03:23:20

+0

'getName'將是一個公共方法,因此您可以在原型而不是靜態方式上定義它,如果沒有任何目的將其公開化或在原型中,則會定義一個靜態方法。 – 2009-11-20 03:23:53

2

原型就像一個類的定義,但它可以動態更改。每當你實例化一個特定類型的對象時,它都會使用原型作爲模板。

如果更改原型,則該類型的對象將具有這些更改。