• 探讨 JS 的面向对象中继承的那些事


    最近学了 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>

  • 相关阅读:
    Linux中大括号{}的应用
    shell script编程(1)>>学生成绩管理系统
    不同版本的Linux防火墙关闭和开启
    shell script的执行方式区别
    包管理介绍(DPKG,APT,RPM,YUM,DNF)
    MBR与GPT,BIOS与UEFI..总结
    Windows10下安装Ubuntu的错误总结
    学生管理系统及票务管理系统总结
    python 3.x和python 2.x下的换行问题
    输出整数各位数字
  • 原文地址:https://www.cnblogs.com/developerL/p/js.html
Copyright © 2020-2023  润新知