ES6里Class的Extends继承原理

Class的方法都加在原型链上

JS的原型链继承的本质是根据__proto__一层一层往上找
继承的时候只需要把子类的原型对象prototype里的__proto__属性指向父类的prototype即可
这就好理解Extends在干嘛了

    class A {
        // constructor也是定义在A的原型链上
        constructor(x,y){
            this.x = x;
            this.y = y;
        }
        // 直接加在了function A 的原型链式
        one(){
            return 1;
        }
    }
    
    class B extends A{
        constructor(){
            //相当于A.prototype.constructor.call(this)  
            super(1,2)
        }
    }
    var x = new B()
    console.log(x)

ES6里Class的Extends继承原理_第1张图片

继承的时候extends干了什么

extends在实现继承方面,本质上也是原型链继承,该方法实现了两步原型链继承

第一步是将类的原型对象(prototype)里的__proto__指向父类的原型对象:

B.prototype = Object.create(A.prototype, {constructor:{value: B}})
即将B.prototype.__proto__ =A.prototype
ES6里Class的Extends继承原理_第2张图片

第二步是将类的__proto__指向父类:

(子类是父类构建出的函数对象,需要指定对象的__proto__)
Object.setPrototypeOf(B, A);
即将B.__proto__ =A (B由A构造而来)
ES6里Class的Extends继承原理_第3张图片

babeljs对extends语法糖的部分编译结果

function _inherits(subClass, superClass) {
    //对superClass进行类型判断
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  //子类的prototype继承父类的prototype
  //也就是说执行后 subClass.prototype.__proto__ === superClass.prototype; 这条语句为true
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { 
        value: subClass, 
        writable: true, 
        configurable: true 
    }
  });
  //子类是父类构建出的函数对象,需要指定对象的__proto__
  if (superClass) _setPrototypeOf(subClass, superClass);
} 

联系寄生组合继承

可以发现ES6类的继承其实就是基于寄生组合继承来实现的

function inheritPrototype(subType, superType){
    var prototype = object(superType.prototype); // 创建了父类原型的浅复制
    prototype.constructor = subType;             // 修正原型的构造函数
    subType.prototype = prototype;               // 将子类的原型替换为这个原型
}

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);
}

你可能感兴趣的:(es6,javascript,继承,原型链,html5)