class繼承作了什麼?

目的

以babel編譯的class繼承爲基礎,瞭解目前class繼承的原理express

理解過程

babel編譯結果

Reference: babel Try it out!bash

class a extends b{
  constructor(){
    super()
    this.c= "haha"
  }
}
複製代碼

被編譯爲babel

繼承作了什麼?

第一步 _inherits(a,_b)實現繼承

function _inherits(subClass, superClass) {
  if (typeof superClass !== 'function' && superClass !== null) {
    throw new TypeError('Super expression must either be null or a function');
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, 
    { constructor: { value: subClass, writable: true, configurable: true } });
  if (superClass) _setPrototypeOf(subClass, superClass);
}
複製代碼

其中重要的是:函數

一、實現原型鏈繼承:subClass.prototype.__proto__ = superClass.prototypeui

subClass.prototype = Object.create(superClass && superClass.prototype, 
    { constructor: { value: subClass, writable: true, configurable: true } });
解釋:
    Object.create()方法建立一個新對象,使用現有的對象來提供新建立的對象的__proto__;
    現有對象是superClass.prototype,新建立對象是subClass.prototype;
    將現有對象賦給新建立的對象的__proto__
結論:
    這一步實現了原型鏈的繼承
複製代碼

reference: MDN Object.create()this

二、實現靜態屬性繼承:subClass.__proto__ = superClassspa

function _setPrototypeOf(o, p) {
  _setPrototypeOf =
    Object.setPrototypeOf ||
    function _setPrototypeOf(o, p) {
      o.__proto__ = p;
      return o;
    };
  return _setPrototypeOf(o, p);
}
if (superClass) _setPrototypeOf(subClass, superClass);

解釋:
    _setPrototypeOf(subClass, superClass)設置subClass的__proto__爲superClass;
    這樣全部經過subClass.property訪問的屬性若是在subClass上找不到,就會去superClass上找
結論:
    這一步實現了靜態屬性的繼承
複製代碼

第二步 return constructor返回構造函數

其中重要的是:prototype

三、調用父類的構造函數:super()code

function _possibleConstructorReturn(self, call) {
  if (call && (_typeof(call) === 'object' || typeof call === 'function')) {
    return call;
  }
  return _assertThisInitialized(self);
}

function _assertThisInitialized(self) {
  if (self === void 0) {
    throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
  }
  return self;
}

function _getPrototypeOf(o) {
  _getPrototypeOf = Object.setPrototypeOf
    ? Object.getPrototypeOf
    : function _getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
      };
  return _getPrototypeOf(o);
}

_this = _possibleConstructorReturn(this, _getPrototypeOf(a).call(this));

解釋:
    根據第一步的第二點subClass.__proto__ = superClass;
    因而_getPrototypeOf(a)返回的是a.__proto__也就是superClass;
    所以_this = superClass.call(this);
    父類中掛在this上的屬性就被掛到子類的this上了
結論:
    這一步實現了父類構造函數的調用
複製代碼

結論

目前的class繼承主要實現瞭如下繼承效果cdn

一、原型鏈繼承

二、靜態屬性繼承

三、調用父類構造函數以得到父類構造函數this上的屬性

相關文章
相關標籤/搜索