13

理解ES6继承extends

1.在es6中对继承有了更友好的方式。在下面的继承中那到底在extends的时候做了什么,super()又是代表什么意思。

class People{
constructor(name, age) {
  this.name = name;
  this.age = age;}
  
say(){
  alert("hello")}
  
static see(){
  alert("how are you")}}

class lily extends People{
  constructor(){
     super()}
  goodbye(){alert("goodbye")}}

2.解析extendssuper()

  • ①在前面的文章中有提及class声明类的原理:https://segmentfault.com/a/11...

  • lilyPeople的子类,首先lily也是一个类;extends的过程中创建了一个自执行函数,并将父类传进去,继承父类之后再返回该子类。lily.__proto__指的是当前对象所属类的原型,也就是Object.getPrototypeOf(lily).

    var lily = function(_People) {
       inherits(lily, _People);  //第一步,继承父类原型
       function lily() {         //第二步,继承父类对象属性
         return _possibleConstructorReturn(this, (lily.__proto__ || Object.getPrototypeOf(lily)).call(this));}
       createClass(lily, [{     //第三步,创建子类自己的方法
        key: "goodbye",
        value: function goodbye() {
        alert("goodbye");}}]);
       
       return lily;
     }(People);
  • ③继承的过程:一般继承分两步,call继承+原型的继承 (分别继承父类对象属行和原型属性)

    • 第一步:继承父类的原型,通过Object.create,第一个参数是创建一个对象的原型,定义原型上的属性constructor指向subclass;把父类的原型方法继承给子类原型;

      function inherits(subClass, superClass) {
         subClass.prototype = Object.create(superClass && superClass.prototype, {
           constructor: {
             value: subClass,
             enumerable: false,
             writable: true,
             configurable: true
           }
         });
         if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
       }
    • 第二步:call继承,就是super()的处理过程,super()的实质就是People.call(this);把父类的对象方法继承给子类对象;这也是为什么在es6的继承时必须要加上super(),因为不加的话无法继承到父类的对象属性。

      function _possibleConstructorReturn(self, call) { 
         //call指的是Object.getPrototypeOf(lily)).call(this),也就是People.call(this)
         return call && (typeof call === "object" || typeof call === "function") ? call : self;
    • 第三部:创建子类自己的方法。 可以参考class里面的实现过程

总的来说es6extends的实质和以前的继承方式是一致 的,但是有了更好的,更清晰的表现形式。


何凯
966 声望174 粉丝

Never too late to learn!