js利用原型對象實現繼承--Es5實現的面向對象方式

利用call和原型對象實現繼承函數

 1 //3.利用call和原型對象實現繼承
 2   //父構造函數
 3   function Father(name,age){
 4     //this指向父構造函數的對象實例
 5     this.name = name ;
 6     this.age = age;
 7     this.sing = function(){
 8         console.log('sing')
 9     }
10   }
11   //給父親添加了money方法
12   Father.prototype.money=function(){
13     console.log('100萬!')
14   }
15   //子構造函數
16   function Son(name,age,score){
17     //調用父構造函數,並修改Father的this爲兒子的this,以達到調用父方法
18     Father.call(this,name,18);
19     this.score = score;
20   }
21   var wb = new Son('小王八',8,100)
22   console.log(wb);

運行結果:測試

 

 

 能夠看到利用call能夠修改父親函數的this,使它變成子函數的this,然而繼承過來的只有父親函數裏面定義的方法,父親而外經過原型對象添加的方法,this

兒子並不可使用,與咱們想的繼承仍是有所出入,那麼這麼解決呢?spa

直接把父親的原型賦值給兒子好嗎?prototype

 1  //3.利用call和原型對象實現繼承
 2   //父構造函數
 3   function Father(name,age){
 4     //this指向父構造函數的對象實例
 5     this.name = name ;
 6     this.age = age;
 7     this.sing = function(){
 8         console.log('sing')
 9     }
10   }
11   //給父親添加了money方法
12   Father.prototype.money=function(){
13     console.log('100萬!')
14   }
15   //子構造函數
16   function Son(name,age,score){
17     //調用父構造函數,並修改Father的this爲兒子的this,以達到調用父方法
18     Father.call(this,name,18);
19     this.score = score;
20   }
21    Son.prototype =  Father.prototype ;
22   var wb = new Son('小王八',8,100)
23   var f = new Father('爸爸',50)
24   console.log(wb);
25   console.log(f)

運行截圖:3d

 

 

 咱們能夠看到父親和兒子的對象原型_proto_好像都有了money,那是否是兒子成功繼承了父親的函數了呢?code

可是因爲父親有本身的函數,那麼兒子也要有本身的函數,好比考試,咱們給兒子添加考試函數對象

//3.利用call和原型對象實現繼承
  //父構造函數
  function Father(name,age){
    //this指向父構造函數的對象實例
    this.name = name ;
    this.age = age;
    this.sing = function(){
        console.log('sing')
    }
  }
  //給父親添加了money方法
  Father.prototype.money=function(){
    console.log('100萬!')
  }
  //子構造函數
  function Son(name,age,score){
    //調用父構造函數,並修改Father的this爲兒子的this,以達到調用父方法
    Father.call(this,name,18);
    this.score = score;
  }
   Son.prototype =  Father.prototype ;//把父親的原型賦值給兒子
   //給兒子的原型添加本身的方法
   Son.prototype.exam = function(){
        console.log('w我考了100分!')
   }
  var wb = new Son('小王八',8,100)
  var f = new Father('爸爸',50)
  console.log(wb);
  console.log(f)

 

運行結果:blog

 

 

 從結果上面看,咱們發現果真兒子要考試,添加成功,可是仔細一看,爸爸也要考試了!繼承

爲何會這樣呢,看下圖

由於咱們上面直接把父親的原型對象給了兒子,其實至關於把地址直接賦給兒子了,那麼兒子若是改了什麼,父親也會隨之改動,不符合繼承的性質。

正確方法:

// Son.prototype =  Father.prototype ;//把父親的原型賦值給兒子有問題,此處爲地址賦值,會引起錯誤
   Son.prototype = new Father();//把上面的修改爲這個
 1 //3.利用call和原型對象實現繼承
 2   //父構造函數
 3   function Father(name,age){
 4     //this指向父構造函數的對象實例
 5     this.name = name ;
 6     this.age = age;
 7     this.sing = function(){
 8         console.log('sing')
 9     }
10   }
11   //給父親添加了money方法
12   Father.prototype.money=function(){
13     console.log('100萬!')
14   }
15   //子構造函數
16   function Son(name,age,score){
17     //調用父構造函數,並修改Father的this爲兒子的this,以達到調用父方法
18     Father.call(this,name,18);
19     this.score = score;
20   }
21    //Son.prototype =  Father.prototype ;//把父親的原型賦值給兒子有問題,此處爲地址賦值,會引起錯誤
22    Son.prototype = new Father();
23    //給兒子的原型添加本身的方法
24    Son.prototype.exam = function(){
25         console.log('w我考了100分!')
26    }
27   var wb = new Son('小王八',8,100)
28   var f = new Father('爸爸',50)
29   console.log(wb);
30   console.log(f)

運行結果:

 

咱們看到兒子可使用父親的函數,也有了本身獨特的函數。

上面實際修改了 Son.prototype =  Father.prototype ;

修改後變成:Son.prototype = new Father(),實際操做以下:只是拿到了Father的實例對象,而後fanther的實例對象能夠拿到father原型對象的money方法,

並且兒子添加本身的方法最多修改了father的實例對象,父親的構造函數沒有影響。

 

可是上面仍是有問題,由於Son.prototype = new Father(),把Father的實例對象賦值給了兒子,看似全部東西都解決了,

可是兒子裏面的constructor指向父親的構造函數了,因此還需修改兒子的constructor指向本身的構造函數。

 1 //3.利用call和原型對象實現繼承
 2   //父構造函數
 3   function Father(name,age){
 4     //this指向父構造函數的對象實例
 5     this.name = name ;
 6     this.age = age;
 7     this.sing = function(){
 8         console.log('sing')
 9     }
10   }
11   //給父親添加了money方法
12   Father.prototype.money=function(){
13     console.log('100萬!')
14   }
15   //子構造函數
16   function Son(name,age,score){
17     //調用父構造函數,並修改Father的this爲兒子的this,以達到調用父方法
18     Father.call(this,name,18);
19     this.score = score;
20   }
21    //Son.prototype =  Father.prototype ;//把父親的原型賦值給兒子有問題,此處爲地址賦值,會引起錯誤
22    Son.prototype = new Father();//把父親實例對象賦給兒子
23    //把對象賦給兒子後,兒子的constructor也指向父親了,須要手動指回兒子
24    //給兒子的原型添加本身的方法
25    Son.prototype.exam = function(){
26         console.log('w我考了100分!')
27    }
28   var wb = new Son('小王八',8,100)
29   var f = new Father('爸爸',50)
30   console.log(wb);
31   console.log('---------------開始測試----------------------')
32   console.log('------修改前兒子的constructor指向-------------')
33   console.log(Son.prototype.constructor)
34   Son.prototype.constructor = Son;//修改指向
35   console.log('------修改後兒子的constructor指向-------------')
36   console.log(Son.prototype.constructor)
37   console.log('---------------結束測試----------------------')
38   console.log(f)

 

 

運行結果:

 

 固然這裏很麻煩,由於是Es5的時候寫繼承必須這樣,Es6就簡單了!

相關文章
相關標籤/搜索