深刻理解Javascript protype

深刻理解Javascript protype html

 JavaScript並非一種面向對象的程序設計語言,嚴格來說,它並無什麼類的概念,頂多只是JSON對象而已,然而在JavaScript中有prototype這個關鍵字,利用它,咱們能夠間接地實現一些面向對象的特性。 瀏覽器

?
簡單的封裝實現
1
2
3
4
5
6
7
8
9
10
varUser =function() {
    this.username ='username';
    this.password ='password';
    this.toString =function() {   
        returnthis.username +':'+this.password;
    }
}
 
varuser =newUser();
document.write(user +'<br />');

  這是一個很簡單的封裝實現,此時的User能夠被視爲一個「類」,這裏還有一個方法叫作toString,實際上,在須要字符串的地方,對象的toString方法會自動被調用。 函數

  若是在上面這個例子中,toString沒有被定義在User裏面,也能夠經過prototype關鍵字來定義在外部,效果是等價的。 post

?
在外部定義成員函數
1
2
3
User.prototype.toString =function() {
    returnthis.username +':'+this.password;
};

  若是在這個例子中沒有寫prototype關鍵字,那麼user對象其實是沒有toString這個函數能夠調用的,由於沒有prototype表明這個toString函數僅被定義在User自己之上。 this

  這是什麼原理呢? spa

  首先,使用new關鍵字進行新對象user的構造時,是調用了上面賦值給User的匿名函數,這個函數賦予了新對象user一些屬性,就像在函數體中所寫的那樣。若是toString沒有被定義在裏面,那麼此時user只有username和password兩個屬性。 prototype

  若是在外部定義的toString沒有加上prototype關鍵字,那麼會發生什麼狀況呢?User對象具備了toString方法,然而User自己卻沒有username和password。所以,此時User的username與password均爲undefined,有沒有以爲比較像面嚮對象語言中的靜態方法呢?是的,相同點在於:咱們能夠經過「類名」直接調用該方法,該方法不能使用「非靜態」成員。 設計

  若是在toString被定義在User.prototype之下,user對象就會具備toString方法,這是爲何呢?由於每一個對象都隱含了一個名爲__proto__的屬性,至關於在User構造函數的最後增長了: htm

?
在外部定義成員函數
1
this.__proto__ = User.prototype;//注意,這個__proto__是內部名稱,不一樣瀏覽器實現不一樣名稱也可能不相同。

  prototype這個特殊的屬性在構造函數定義時被初始化,初始化時包含了User的構造函數自己和本身的__proto__屬性,當用戶經過User.prototype的方式定義新屬性或方法的時候,這些屬性或方法就被增長到User.prototype這個JSON對象之中。因爲this.__proto__ = User.prototype;的緣故,調用這個構造函數構造的全部對象的__proto__屬性中,都包含有這個新屬性或方法。所以,實際上toString並無成爲user下的一個方法,而是user.__proto__下的一個方法。 對象

  而後,實際執行user.toString()時,瀏覽器將檢查user是否具備toString方法能夠調用,若是沒有,瀏覽器將繼續檢查其__proto__屬性中是否有toString方法,若是仍然沒有,則繼續遞歸向上尋找這個__proto__屬性的__proto__屬性。如此,就能夠解釋爲何prototype下定義的方法,均可以被該「類」的全部實例調用的緣由了。

相關文章
相關標籤/搜索