js继承实现

1.原型继承

// 第一:原型继承
    // 方法:让父类中的属性和方法在子类实例的原型链上
    // 1.  child.prototype = new father(200)
    // 2.  child.prototype.constructor = child
    // 特点:
    // 1.  把父类的原型放到子类的实例的原型链上,实例调用这些方法,基于__proto__ 原型链查找机制完成的
    // 2.  子类可以重写父类上的方法(会导致父类的其它实例有影响)
    // 3.  父类的私有或公有的属性方法,都会变成子类中公有的属性和方法
    function A(x) {
      this.x = x
    }
    A.prototype.getX = function () {
      console.log(this.x)
    }
    function B(y) {
      this.y = y
    }
    B.prototype = new A(200)
    B.prototype.constructor = B
    B.prototype.getY = function () {
      console.log(this.y)
    }

    let b1 = new B(100);
    console.log(b1.y) // 100
    b1.getY() // 100

    b1.getX() //200

2.call继承

// 第二:call继承
    // 方法:子类方法中把父类当作普通函数执行,让父类的this指向子类的实例,相当于给子类的实例设置了很多私有的属性和方法
    // 1.  只能继承父类私有的属性或方法(因为是把父类当作普通函数执行的,和其原型上的属性方法没关系)
    // 特点:
    // 1.  父类私有的变子类私有的
    function A(x) {
      this.x = x
    }
    A.prototype.getX = function () {
      console.log(this.x)
    }
    function B(y) {
      // this.B的实例b1
      A.call(this,200) // b1.x = x
      this.y = y
    }

    B.prototype.getY = function () {
      console.log(this.y)
    }

    let b1 = new B(100);
    console.log(b1.x) // 200
    console.log(b1.y) // 100
    b1.getY() // 100

    b1.getX() //200

3.寄生组合继承(call+原型creat)

// 第三:寄生组合继承(call+原型creat)
      // 方法:子类方法中把父类当作普通函数执行,让父类的this指向子类的实例,相当于给子类的实例设置了很多私有的属性和方法
      // 1.  使用call继承父类私有的属性或方法(因为是把父类当作普通函数执行的,和其原型上的属性方法没关系)
      // 2.  使用Object.create(OBJ)
      // 特点:
      // 1.  父类私有和公有分别是子类私有和公有
      function A(x) {
        this.x = x
      }
      A.prototype.getX = function () {
        console.log(this.x)
      }
      function B(y) {
        // this.B的实例b1
        A.call(this,200) // b1.x = x
        this.y = y
      }


      // Object.create(OBJ):创建一个空对象,让空对象__proto__指向OBJ(或者说把OBJ作为新创建对象的原型)
      // Object.create(OBJ)  方法IE不兼容,所以自己写一个
      B.prototype = Object.create(A.prototype)
      B.prototype.constructor = B



      B.prototype.getY = function () {
        console.log(this.y)
      }
  
      let b1 = new B(100);
      console.log(b1.x) // 200
      console.log(b1.y) // 100
      b1.getY() // 100
  
      b1.getX() //200

4.重写Object.create(OBJ)方法  

<script>
    // 重写Object.create(OBJ)方法  

    // 方法一:重写Object.create(OBJ)方法  
    // 原理:创建一个对象,让对象的原型链指向某一个东西
    Object.create = function (obj) {
      let o = {};
      o.__proto__ = obj;
      return o;
      // 意思对,但__proto__在IE不让用
    }

    // 方法二:
    // 只要能创造某一个类的实例,那么这个实例原型链就指向当前类的原型,那么首先得有一个类,这个类的原型就是参数obj
    Object.create = function (obj) {
      function Fn() { }; // 创造一个类
      Fn.prototype = obj; // 让这个类的原型指向obj
      return new Fn() // new Fn(),创造Fn类的实例,则这个实例原型链指向当前类Fn的原型obj
    }
  </script>

5.es6 继承

// 语法要求,基于class创造出的类不能当普通函数执行,如A(),所以call也无法使用,
  class A{
    constructor(x){
      this.x = x
    }
    getX(){
      console.log(this.x)
    }
  }
  // 语法写法
  // 原型上加方法如上getX
  // 原型上加属性如下
  // A.prototype.shuxing = 'shuxingzhi'

  // class B{
  //   constructor(y){
  //     this.y = y
  //   }
  //   getY(){
  //     console.log(this.y)
  //   }
  // }

  // =>ES6的继承
  // class 子类 extends 父类 {}
  // =>B.prototype.__proto__ = A.prototype
  class B extends A{
    constructor(y){
      // 子类继承父类可以不写constructor,但写了constructor就必须写super(200); super相当于cal继承
      super(200); // A.call(this,200) 把父类当作普通方法执行,给方法传递参数,让方法中的this是子类的实例
      this.y = y
    }
    getY(){
      console.log(this.y)
    }
  }

  
  // B.prototype = Object.create(A.prototype) //es6不允许重定向原型的指向
  let b1 = new B(100)
  console.log(b1)
原文地址:https://www.cnblogs.com/forever-xuehf/p/12768393.html