• JS实现继承的几种方式


    一、借用构造函数

    1 function Father(val){
    2     this.val=val;
    3     this.arr=[1];
    4 }
    5 function Child(val){
    6     Father.call(this,val);      
    7 }
    8 var child1=new Child();
    9 console.log(child1.val);

    缺点:子类无法继承父类的原型对象,并没有真正的实现继承(部分继承)

    如果给上述代码再添加几行:

     1 function Father(val){
     2     this.val=val;
     3     this.arr=[1];
     4     this.fun=function(){
     5         //....
     6     }
     7 }
     8 function Child(val){
     9     Father.call(this,val);      
    10 }
    11 var child1=new Child(1);
    12 var child2=new Child(2);
    13 child1.arr.push(2);
    14 
    15 console.log(child1.val);    //1
    16 console.log(child2.val);    //2
    17 
    18 console.log(child1.arr);    //1,2
    19 console.log(child2.arr);    //1
    20 
    21 console.log(child1.fun === child2.fun);   // false

    上面代码中21行报错,是因为无法继承方法,每个子类实例都有一个新的方法,无法实现函数复用

    二、原型链

     1 function Father(){    //父类            
     2     this.name='张三';
     3     this.arr=[1];
     4 }
     5 function Child(){       //子类
     6     this.type="hello"
     7 }
     8 Child.prototype=new Father();  //子类的原型等于父类的实例
     9 var child1=new Child();        //实例化一个子类对象
    10 console.log(child1.name); 

    缺点:原型对象的属性是共享的

    如果给上述代码再添加几行:

     1 function Father(){    //父类            
     2     this.name='张三';
     3     this.arr=[1];
     4 }
     5 function Child(){       //子类
     6     this.type="hello"
     7 }
     8 Child.prototype=new Father();  //子类的原型等于父类的实例
     9 
    10 var child1=new Child();        //实例化一个子类对象
    11 var child2=new Child();        //实例化一个子类对象
    12 child1.name='李四'
    13 child1.arr.push(2);
    14 
    15 console.log(child1.name);    //李四
    16 console.log(child2.name);    //张三
    17 
    18 console.log(child1.arr);     //1,2
    19 console.log(child2.arr);     //1,2  

    此时就出现了一个问题,第13行代码明明是给child1实例添加了属性,为什么第19行代码显示child2也拥有了该属性呢?这就是原型链继承所存在的问题,原型对象的属性是共享的。

    三、组合式继承

    原型继承+构造函数继承

     1 function Father(){      //父类
     2     this.val=1;         //只在此处声明父类属性
     3     this.arr=[1];
     4 }
     5 Father.prototype.sayHai=function(){    //只在此处声明父类方法
     6     //...
     7 }
     8 function Child(){
     9     Father.call(this);     //构造函数继承
    10 }
    11 Child.prototype=new Father();     //原型链继承
    12 
    13 var child1=new Child();
    14 var child2=new Child();
    15 
    16 console.log(child1.sayHai==child2.sayHai);    //true
    将实例方法放到原型对象里,以实现函数复用,同时还要保留借用构造函数方式的优点
    优点:不存在属性共享问题,函数可复用
     缺点:父类构造函数被调用了两次,代码冗余
    四、寄生组合继承
     
  • 相关阅读:
    IndexFlatL2、IndexIVFFlat、IndexIVFPQ三种索引方式示例
    Faiss流程与原理分析
    快速排序(快排)
    SSM框架整合Demo
    基于Logistic回归和sigmoid函数的分类算法推导
    Libsvm java工程实践
    LibSvm流程及java代码测试
    排除文件中空行和注释行内容
    linux三剑客-sed命令使用方法
    文件中添加多行内容方法
  • 原文地址:https://www.cnblogs.com/endlessmy/p/8634129.html
Copyright © 2020-2023  润新知