美文网首页
JS继承方法详解以及优缺点

JS继承方法详解以及优缺点

作者: 匿于烟火中 | 来源:发表于2020-02-26 23:22 被阅读0次

    前置阅读:理解原型、new、构造函数

    构造函数直接实现


    function SuperType(){
        this.property =true;
    }
    
    function SubType(){
          SuperType.call(this);
    }
    
    //修改父类上的原型内容
    SuperType.prototype.getType = function(){
        return 'add';
    }
    var instance = new SubType();
    
    console.log(instance.property);
    //true
    console.log(instance.getType());
    //报错:Uncaught TypeError: instance.getType is not a function
    
    • 问题:通过构造方法继承的子类,可以获取到父类构造函数当中的所有属性。
      • 子类就无法获取到父类prototype上变化的属性和方法。
      • 不好进行函数复用

    原型继承


    function SuperType(){
        this.property =true;
        this.colors = ['red','green'];
    }
    SuperType.prototype.getSuperValue = function(){
        return this.property;
    }
    
    var parent = new SuperType();
    function SubType(){
        this.property = false;//子类重写父类属性
    }
    //把子类的原型设置为父类的一个新的实例对象
    //父类的实例的__proto__中指向它自己的原型对象
    //所以这样子类也可以成功访问到
    SubType.prototype = new SuperType(); 
    SubType.prototype.getSubType = function(){
        return this.property;
    }
    var instance = new SubType();
    console.log(instance.getSuperValue());//false
    instance.colors.push('blue');
    console.log(parent.colors);//'red','green',
    var instance2 = new SubType();
    console.log(instance2.colors);//'red','green','blue'
    
    • 问题:
      • 不同子类实例会共享同一个引用类型数据,所以如果有一个修改了它,其他实例访问到的也是修改之后的。
      • 创建子类实例的时候不能向构造参数传递参数。
    原型继承.PNG

    组合继承:构造函数+原型继承

    function SuperType(){
        this.property =true;
        this.colors = ['red','green'];
    }
    SuperType.prototype.getSuperValue = function(){
        return this.property;
    }
    
    var parent = new SuperType();
    function SubType(arg){
        SuperType.call(this,arg);
        this.property = false;//子类重写父类属性
    }
    
    SubType.prototype = new SuperType(); 
    
    SubType.prototype.getSubType = function(){
        return this.property;
    }
    var instance = new SubType();
    console.log(instance.getSuperValue());//false
    instance.colors.push('blue');
    console.log(instance.colors);//'red','green','blue'
    console.log(parent.colors);//'red','green',
    var instance2 = new SubType();
    console.log(instance2.colors);//'red','green'
    
    • 组合继承,具有了两种集成方式的有点,同时因为借用了父类的构造函数,所以每个子类实例获得了父类的属性。
      • 不足之处:每次都会调用两次超类的构造函数。一次是创建子类原型的时候,另一次是在子类构造函数内部。
    组合继承.PNG

    寄生继承:

    • 调用函数创建对象+增强该对象的属性和方法
     function createAnother(original){
      var clone = object(original);
      clone.sayHi = function(){
        console.log('hi');
      }
      return clone;
    }
    
    var person = {
      name:"sherry",
      friends:['lisa']
    }
    var p = createAnother(person);
    

    最佳实践:寄生组合继承


    function inheritPrototype(subType,superType){
      var prototype = object(superType.prototype);  
      prototype.contructor = subType;
      subType.prototype = prototype;
    }
    

    另一种实现方式:

     function extend(Child, Parent) {
        var F = function(){};
        F.prototype = Parent.prototype;
        Child.prototype = new F();
        Child.prototype.constructor = Child;
        Child.uber = Parent.prototype;
      }
    
    • 只调用一次superType的构造函数
    • 原型链也没有改变

    参考:《Javascript高级教程》

    相关文章

      网友评论

          本文标题:JS继承方法详解以及优缺点

          本文链接:https://www.haomeiwen.com/subject/kduufhtx.html