美文网首页
js继承总结

js继承总结

作者: 一包 | 来源:发表于2019-03-02 10:08 被阅读0次

    最近在准备面试,js继承真的好乱鸭鸭鸭鸭,整理一下~希望可以记得!
    (参考:https://blog.csdn.net/caijixin/article/details/78295676
    https://juejin.im/entry/5bcb2f695188255c2f425251

    1. 借用构造函数继承

    • 通过call、apply方法,使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类(不使用原型)
    • SuperType.call(this);创建子类实例时调用SuperType构造函数,于是SubType的每个实例都会将SuperType中的属性复制一份。
    function SuperType() {
         this.colors = ["red","blue","green"];    
    }
    
    function SubType() {
       //继承了SuperType   --重新创建SuperType构造函数属性的副本
       SuperType.call(this);
    }
    
    ar instance1 = newe SubType();
    instance1.colors.push("black");
    console.log(instance1.colors);  //"red,blue,green,black"
    

    缺点:

    • 只能继承父类的实例属性和方法,不能继承原型上的属性或方法
    • 每个子类都有父类实例的副本,没能做到复用,影响性能

    优点

    • 可以传参,SuperType.call(this,"Nicholas");

    2.原型链方法

    • 利用原型链来实现继承,超类的一个实例作为子类的原型
    function SuperType(){
      this.colors = ["red", "blue", "green"];
    }
    function SubType(){}
    
    SubType.prototype = new SuperType();
    SubType.prototype.constructor=SubType;
    
    
    • SubType.prototype.constructor=SubType;如果没有这句SubType.prototype.constructor会指向SuperType

    缺点:

    • 如果父类包含引用类型的属性,那么子类所有实例都会共享该属性。
    • 在创建子类型的实例时,不能向超类的构造函数中传递传递参数
    function SuperType(){
      this.colors = ["red", "blue", "green"];
    }
    function SubType(){}
    
    SubType.prototype = new SuperType();
    SubType.prototype.constructor=SubType;
    
    var instance1 = new SubType();
    instance1.colors.push("black");
    alert(instance1.colors); //"red,blue,green,black"
    
    var instance2 = new SubType(); 
    alert(instance2.colors); //"red,blue,green,black"
    
    

    3.组合继承方法

    • 组合上面两种方法就是组合继承方法。用原型链继承实现对原型属性和方法的继承,借用构造函数继承方法实现对实例属性的继承。
    function SuperType(name){
      this.name = name;
      this.colors = ["red", "blue", "green"];
    }
    SuperType.prototype.sayName = function(){
      alert(this.name);
    };
    
    function SubType(name, age){
      // 继承属性
      // 第二次调用SuperType()
      SuperType.call(this, name);
      this.age = age;
    }
    
    // 继承方法
    // 构建原型链
    // 第一次调用SuperType()
    SubType.prototype = new SuperType(); 
    // 重写SubType.prototype的constructor属性,指向自己的构造函数SubType
    SubType.prototype.constructor = SubType; 
    var instance1 = new SubType("Nicholas", 29);
    
    

    缺点:

    • 实际上子类上会拥有超类的两份属性,只是子类的属性覆盖了超类的属性
      (第一次调用SuperType()给SubType.prototype写入两个属性name,color。给instance1写入两个属性name,color)

    4.原型式继承

    • 利用一个空对象作为中介,将某个对象直接赋值给空对象构造函数的原型。
    function object(obj){
        function F(){}
        F.prototype=obj;
        return new F()
    }
    
    

    object()对传入其中的对象执行了一次浅复制,将构造函数F的原型直接指向传入的对象。

    var person = {
      name: "Nicholas",
      friends: ["Shelby", "Court", "Van"]
    };
    
    var anotherPerson = object(person);
    
    

    ES5中存在Object.create()的方法,能够代替上面的object方法

    缺点

    • 原型链继承多个实例的引用类型属性指向相同,存在篡改的可能
    • 无法传递参数

    优点

    • 可以继承非构造函数(以上例子就是)

    5.寄生式继承

    • 在原型式继承的基础上,增强对象,返回构造函数。
    function createAnother(original){
      var clone = object(original); // 通过调用 object() 函数创建一个新对象
      clone.sayHi = function(){  // 以某种方式来增强对象
        alert("hi");
      };
      return clone; // 返回这个对象
    }
    
    
    
    • 函数的主要作用是为构造函数新增属性和方法,以增强函数

    缺点

    • 同原型继承

    6.寄生组合继承

    • 结合借用构造函数传递参数和寄生模式实现继承
    function inheritPrototype(subType, superType){
        var prototype=Object.create(surperType.prototype);// 创建对象,创建父类原型的一个副本
        prototype.constructor=subType;// 增强对象,弥补因重写原型而失去的默认的constructor 属性
        subType.prototype=prototype;// 增强对象,弥补因重写原型而失去的默认的constructor 属性
    }
    
    // 父类初始化实例属性和原型属性
    function SuperType(name){
      this.name = name;
      this.colors = ["red", "blue", "green"];
    }
    SuperType.prototype.sayName = function(){
      alert(this.name);
    };
    
    // 借用构造函数传递增强子类实例属性(支持传参和避免篡改)
    function SubType(name, age){
      SuperType.call(this, name);
      this.age = age;
    }
    / /将父类原型指向子类
    inheritPrototype(SubType, SuperType);
    
    // 新增子类原型属性
    SubType.prototype.sayAge = function(){
      alert(this.age);
    }
    

    缺点

    • 完美实现继承,解决了组合式继承带两份属性的问题

    相关文章

      网友评论

          本文标题:js继承总结

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