类的方法都加入了原型链。JS原型链继承的本质是根据__proto__逐层寻找继承。父类中的__proto__属性足以指向父类的原型,所以很容易理解Extends在干什么{这个.x=x;这个.y=y;}//直接加入到函数A的原型链中one(){return1;}}classBextendsA{constructor(){//相当于A.prototype.constructor.call(this)super(1,2)}}varx=newB()console.log(x)继承的时候,什么extends做了吗?在继承的实现上,extends本质上是原型链继承。该方法实现了两步原型链继承在大多数浏览器的ES5实现中,每个对象都有一个__proto__属性,指向对应构造函数的prototype属性。Class作为构造函数的语法糖,同时具有prototype属性和__proto__属性,所以同时存在两条继承链。(1)子类的__proto__属性表示构造函数的继承,始终指向父类。(子类构造函数(Child)的原型(__proto__)指向父类构造函数(Parent),)(2)子类原型属性的__proto__属性表示方法的继承,始终指向方法的原型父类属性。第一步是将类的原型对象(prototype)中的__proto__指向父类的原型对象:B.prototype=Object.create(A.prototype,{constructor:{value:B}})是即将B.prototype.__proto__=A.prototype第二步,将类的__proto__指向父类:(子类是父类构造的函数对象,需要指定对象的__proto__)对象.setPrototypeOf(B,A);.__proto__=A(B由A构造)最后需要在构造函数中继承属性,方法内部写的有点绕,不过最后还是通过apply(this,arguments)(function(_A){//继承原型对象上的属性和方法_inherits(B,_A);functionB(){_classCallCheck(this,B);//在构造函数中继承实例属性和方法return_possibleConstructorReturn(this,_getPrototypeOf(B).apply(this,arguments));}返回B;})(A);babeljs编译了extends的部分语法糖function_inherits(subClass,superClass){//对superClass进行类型判断if(typeofsuperClass!=="function"&&superClass!==null){thrownewTypeError("Superexpressionmusteither为空或函数");}//子类的原型继承了父类的原型//也就是说执行完后subClass.prototype.__proto__===superClass.prototype;这个说法是真的subClass.prototype=Object。创建(superClass&&superClass.prototype,{构造函数:{值:子类,可写:真,可配置:真}});//子类是父类构造的函数对象,需要指定对象的__proto__if(superClass)_setPrototypeOf(subClass,superClass);}联系寄生组合继承(调用+寄生封装)寄生原理组合继承:使用借用的构造函数(call)继承父类this声明的属性/方法,并通过寄生封装函数设置父类原型子类原型的原型继承the的原型声明的属性/方法父类可以发现ES6类的继承其实是基于寄生组合继承来实现的。functioninheritPrototype(subType,superType){//原型继承:浅拷贝superType._proto_指向:原型。\_\_proto\_\_=superType.prototype;varprototype=Object.create(superType.prototype);//subType.prototype.\_\_proto\_\_=superType.prototype;subType.prototype=原型;//用这个原型替换子类的原型prototype.constructor=subType;//修复原型的构造函数}functionSuperType(name){this.name=name;this.colors=["red","blue","green"];}SuperType.prototype.sayName=function(){alert(this.name);};functionSubType(name,age){SuperType.call(这个,名字);this.age=age;}//核心:因为是父类原型的拷贝,所以不包含父类的构造函数,不会调用两次父类的构造函数造成浪费inheritPrototype(SubType,SuperType);SubType.prototype.sayAge=function(){alert(this.age);}
