继承的那点事

175 阅读1分钟

js的继承有两种,一种是ES5继承,另一种是ES6的类继承。

ES5继承主要是是通过修改原型链来实现的继承。实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。Class的继承是通过external来继承,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this

继承后的原型链

class A {}
class B extends A {}

b.__proto__ === B.prototype
B.prototype.constructor === B;

B.__proto__ === A;
B.prototype.__proto__ === A.prototype


代码实现ES5继承

列举了主要的两种方式

  1. 常见的原型链继承 造成的问题:因为引用类型的原型属性会被所有实例共享,导致如果Person里的this.name如果是引用类型的话,通过Man生成的实例都会共享,有一个实例修改,另一个实例拿到的结果也会变。
 function Person(name) {
    this.name = name;
    this.getName = () => {
      return this.name;
    };
  }
  Person.prototype.setName = function(name) {
    this.name = name;
  };

  function Man(name){
    this.sex='male';
    this.getSex = () => {
      return this.sex;
    };
  }
  
 //* 直接修改原型链
 Man.protoType = new Person('参数');
 Man.protoType.constructor = Man;
  1. 寄生式继承(推荐)
 function Person(name) {
    this.name = name;
    this.getName = () => {
      return this.name;
    };
  }
  Person.prototype.setName = function(name) {
    this.name = name;
  };

  function Man(name){
      
    Person.call(this,name);//等同于class继承里的super作用
      
    this.sex='male';
    this.getSex = () => {
      return this.sex;
    };
  }

 const protoType = Object.create(Person.prototype);
 protoType.constructor = Man;
 Man.protoType = protoType;
 

Object.creat:这个方法接收两个参数:一个作用新对象原型的对象和(可选的)一个为新对象定义额外属性的对象;