美文网首页
js原型继承的几种方法

js原型继承的几种方法

作者: AAA前端 | 来源:发表于2021-04-13 12:54 被阅读0次

    1. 原型链继承

    利用原型链来实现继承,父类的一个实例作为子类的原型

    function child(){
      this.xx = 'xx'; //子类自己的定义
    }
    child.prototype = new parent();
    //这里new parent()父类对象并没有constructor属性,需要后面加上
    child.prototype.constructor = child
    
    

    原理: 子类的原型对象指向 父类的实例, 当子类实例找不到属性和方法时,会沿着原型链往上找。
    优点:简单,既是子类实例也是父类实例,父类新加原型方法或者属性,子类都能访问到
    缺点:

    1. 不能实现多继承,所有子类的实例的原型都共享一个父类实例属性和方法
    2. 不能传参

    2. 构造函数继承

    通过使用call、apply方法可以在新创建的对象上执行构造函数,用父类的构造函数来增加子类的实例

    原理: 子类的构造函数中执行父类的构造函数,并且改变子类的this绑定

         // 创建子类、添加子类属性。
        function arrange(name){
          Person.call(this,name) // 执行父构造,将This指向本身,拉取父私有属性;
        }
    
    

    优点:简单,直接父类的属性和方法
    缺点:无法继承原型链上的属性方法

    3. 寄生组合式继承

    将父类原型对象直接赋值给子类的构造函数,再将空属性的构造函数实例赋值给子类原型对象

    function Parent(name){
      this.name = name
    }
    Parent.prototype.getName = function(){
      return this.name
    }
    // 创建子类、添加子类属性。
    function Child(name){
      Parent.call(this, name)// 执行父构造,将This指向本身,拉取父私有属性;
    }
    
     // 子类的原型对象指向父类的原型对象
    Child.prototype = Parent.prototype
     // 将constructor指向本身,保证原型链不断。
    Child.prototype.constructor = Child
    

    优点:完美实现继承,解决了组合式继承带两份属性的问题; new Child的时候不用 每次都 new Parent
    缺点: 子类的prototype添加方法会影响 父类的prototype;

    4. 寄生组合式继承(改进)

    将父类原型对象直接赋值给子类的构造函数,再将空属性的构造函数实例赋值给子类原型对象

    function Parent(name){
      this.name = name
    }
    Parent.prototype.getName = function(){
      return this.name
    }
    // 创建子类、添加子类属性。
    function Child(name){
      Parent.call(this, name)// 执行父构造,将This指向本身,拉取父私有属性;
    }
    
     // 子类的原型对象指向父类的原型对象
    // 浅拷贝 解决问题
    Child.prototype = Object.create(Parent.prototype)
     // 将constructor指向本身,保证原型链不断。
    Child.prototype.constructor = Child
    

    优点:完美实现继承,解决了组合式继承带两份属性的问题; new Child的时候不用 每次都 new Parent

    5. 克隆原型链继承

    将等待继承的原型对象克隆,再赋值给继承的原型对象

        // 创建子类、添加子类属性。
        function arrange(name){
          this.name = name;
          this.goShop = function(food){
            console.log(name + '叫你去买'+ food)
          }
        }
        // 创建克隆类型
        function Clone(obj){
          for(var key in obj){
            this[key] = typeof obj[key] == 'object' ? new Clone(obj[key]) : obj[key];
          }
        }
        // 使用Clone构造函数继承原型
        arrange.prototype = new Clone(Person.prototype); 
        // 将constructor指向本身,保证原型链不断。
        arrange.prototype.constructor = arrange; 
    
        //创建arrange新实例,也是Clone实例,却不在是Person实例;
        var newObj = new arrange('李四'); 
        console.log(newObj instanceof Person)  //false
        console.log(newObj instanceof arrange) //true
        console.log(newObj instanceof Clone) //true
        // 克隆成功,可以访问克隆对象的原型对象;
        console.log(newObj)
        console.log(newObj.name) // 李四
        newObj.eat('苹果'); // 李四正在吃:苹果
        newObj.goShop('香蕉'); // 李四叫你去买香蕉
    

    优点:直接通过对象生成一个继承该对象的对象
    缺点:不是类式继承,而是原型式基础,缺少了类的概念

    参考: https://www.jb51.cc/note/413574.html
    https://blog.csdn.net/qq_42926373/article/details/83149347

    相关文章

      网友评论

          本文标题:js原型继承的几种方法

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