JS 繼承總結

      ES裏面沒有真正的繼承,可是能經過某些手段達到繼承效果,從而讓一個類擁有另一個類的方法  類 =>構造函數app

繼承描述某語言環境---魔獸世界 哈!其實我沒玩過  魔獸世界裏面 有Humen類  Humen類裏面有Gnome(侏儒) , gnome有方法say(個人名字) 
有共有屬性ggroup=gnome ,humen 有共有屬性hgroup=humen , 有本身名字 hname 共有方法write();函數

總共共3種繼承方式 一種類繼承 一種是原型繼承 還有一種組合繼承  至於其餘的繼承方式,本質上沒啥區別this

function  humen(name){  //人類類
    this.name=name;
    this.write=function(){
        console.log("write")
    }
}
humen.prototype.hgroup="humen";
new humen('張三');
//傳統的是在gnome裏面創建一個temp屬性 指向humen構造函數,從而去用humen裏面this指向ganme 而後去初始化gnome裏面的屬性和方法(略)
/**下面是類繼承 */
 function gnome(name){    
     this.say=function(){
         console.log(this.name);
     };
     humen.call(this,name);
 }
gnome.prototype.ggroup="gnome";
var gnome=new gnome("李四");
console.log(gnome.name);  //"李四"
console.log(gnome.hgroup);//"underfined"   由此能夠得出這種繼承方式只是借用call 或者apply 來改變this 借用構造函數初始化屬性和方法
 //沒法繼承原型上面的屬性和方法


/*************************下面是原型繼承 ***********************/
function gnome(name){
   this.name=name;
  this.say=function(){
      console.log(this.name);
  }
}
gnome.prototype.ggroup="gnome";
gnome.prototype=new humen(); //   這裏把一些公共的參數傳進去。。。
var gnome=new gnome("李四");
gnome.say();//李四
console.log(gnome.hgroup);  //humen 由此得出這種繼承方式可以繼承原型鏈上面的屬性和方法 可是個體的方法(this.name)須要從新寫一遍


/*************************都用的不爽 前面2種一種不能繼承原型 一種構造函數裏面的屬性須要從新定義 混合繼承***********************/
function gnome(name){
   this.say=function(){ //本身的方法
         console.log(this.name);
     };
     humen.call(this,name);
}
gnome.prototype=new humen(); //new humen裏面name屬性是undefined  被類繼承的name覆蓋
gnome.prototype.ggroup="gnome";
  var gnome1=new gnome("李四");
    gnome1.say();//李四
    gnome.prototype.constructor=gnome; //因爲用原型繼承 構造函數方向指向humen
    console.log(gnome1.hgroup);//"humen"
    console.log(gnome1.ggroup);  //"gnome"

總結:每使用new 關鍵字new一個對象都是在建立一個空對象,改變this指針指向空對象,而後初始化其中屬性和方法,還有_proto_指向原型對象,因此對於一些公用的屬性和方法定義在原型對象之中,避免浪費內存,私有的(與參數相關)則放在構造函數中。類繼承和原型繼承都有各自的弊端,組合繼承則互補,實現完美繼承,注意constructor的指向spa

另外附上某處偷來的,本身以爲比較好的js世界裏面的原型鏈圖:prototype

image

相關文章
相關標籤/搜索