1. 程式人生 > >探討 JS 的面向對象中繼承的那些事

探討 JS 的面向對象中繼承的那些事

通過 嵌套 過程 type round father 賦值 object 同時

最近學了 JS 的面向對象,這篇文章主要是探討 JS 的面向對象中繼承的那些事。

JS中繼承的特點:

1、子類繼承父類;

2、子類可以用父類的方法和屬性

3、子類的改變可以不影響父類

下面用一個例子來說明 JS 的繼承

這段代碼創建了一個父類以及它的原型,同時還創建了一個子類,並繼承了父類的私有屬性

 1 <script>
 2         //這是父類
 3         function Father(name,age,marry){
 4             this.name=name;
 5             this.age=age;
 6             this
.marry=marry; 7 } 8 //父類的原型 9 Father.prototype.showName=function(){ 10 alert(this.name); 11 } 12 13 //子類 14 function Son(name,age,marry,weight){ 15 Father.call(this,name,age,marry); 16 this.weight=weight; 17 }
18 19 </script>

當子類Son想繼承父類的原型時,我的做法一開始是這麽做的

 1 <script>
 2         //這是父類
 3         function Father(name,age,marry){
 4             this.name=name;
 5             this.age=age;
 6             this.marry=marry;
 7         }
 8         //父類的原型
 9         Father.prototype.showName=function
(){ 10 alert(this.name); 11 } 12 13 //子類 14 function Son(name,age,marry,weight){ 15 Father.call(this,name,age,marry); 16 this.weight=weight; 17 } 18 19 //錯誤的做法 20 Son.prototype=Father.prototype; 21 Son.prototype.showAge=function(){ 22 alert(this.age); 23 } 24 var father=new Father(‘王大錘‘,30,true); 25 alert(father.showAge); 26 27 </script>

技術分享圖片

運行的結果可以發現,子類原型的改變影響了父類的原型,父類的原型中本來是沒有showAge方法的,這就違背了前面繼承的第三個特點了。

分析原因:上面代碼的第20行 Son.prototype=Father.prototype;這裏的 ‘=‘ 兩邊都是對象,那麽它代表的意思就是引用,如果是引用的話,左邊的對象改變,肯定會影響了右邊的對象

      所以才出現了子類原型的改變影響了父類的原型。

解決辦法

方法一:核心思路,前面的問題不是說 ‘=‘ 是引用的關系才導致問題的嘛,那這裏就保證 ‘=‘ 永遠是賦值的關系,而不是引用。這裏就定義一個 Clone() 方法,將父類對象拷貝給子類。

    Clone() 方法裏用到遞歸的原因是,在拷貝的過程中對象中可能嵌套對象。

 1 <script>
 2         //這是父類
 3         function Father(name,age,marry){
 4             this.name=name;
 5             this.age=age;
 6             this.marry=marry;
 7         }
 8         //父類的原型
 9         Father.prototype.showName=function(){
10             alert(this.name);
11         }
12 
13         //子類
14         function Son(name,age,marry,weight){
15             Father.call(this,name,age,marry);
16             this.weight=weight;
17         }
18         Son.prototype=new Clone(Father.prototype);
19         Son.prototype.showAge=function(){
20             alert(this.age);
21         }
22         var father=new Father(‘王大錘‘,30,true);
23         alert(father.showAge);
24 
25         //通過克隆對象:核心思路是保證 ‘=‘ 是賦值的關系,而不是引用,也就是保證 ‘=‘ 的右邊不是對象
26         function Clone(obj){
27             for(var i=0;i<obj.length;i++){
28                 if(typeof(obj[key]==‘object‘)){
29                     this.key=new Clone(obj[key]);
30                 }else{
31                     this.key=obj[key];
32                 }
33             }
34         }  
35 </script>

技術分享圖片

這時候的結果父類對象的showAge方法是undefined

方法二:代碼很簡單,但是很難想到,沒有第一個方法那麽好理解。核心思想:對象自身屬性的改變,不會影響其構造函數的屬性的改變。

 1 <script>
 2         //這是父類
 3         function Father(name,age,marry){
 4             this.name=name;
 5             this.age=age;
 6             this.marry=marry;
 7         }
 8         //父類的原型
 9         Father.prototype.showName=function(){
10             alert(this.name);
11         }
12 
13         //子類
14         function Son(name,age,marry,weight){
15             Father.call(this,name,age,marry);
16             this.weight=weight;
17         }
18         function fn(){}
19         fn.prototype=Father.prototype;
20         Son.prototype=new fn();      
21         Son.prototype.showAge=function(){
22             alert(this.age);
23         }
24         var father=new Father(‘王大錘‘,30,true);
25         alert(father.showAge);
26 
27         //通過克隆對象:核心思路是保證 ‘=‘ 是賦值的關系,而不是引用,也就是保證 ‘=‘ 的右邊不是對象
28         // Son.prototype=new Clone(Father.prototype);
29         // function Clone(obj){
30         //     for(var i=0;i<obj.length;i++){
31         //         if(typeof(obj[key]==‘object‘)){
32         //             this.key=new Clone(obj[key]);
33         //         }else{
34         //             this.key=obj[key];
35         //         }
36         //     }
37         // }  
38 </script>

技術分享圖片

探討 JS 的面向對象中繼承的那些事