直入主題。原始碼如下:
class A{
aName = 'A'
constructor(aAge){
this.aAge = aAge
}
static aStatic = 'aStatic'
}
class B extends A{
bName = 'b'
constructor(bAge){
super()
this.bAge = bAge
}
static bStatic = 'bStatic'
}
var b = new B;
使用babel轉換後的程式碼如下:
"use strict";
// typeof
function _typeof(obj) {}
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 },
});
Object.defineProperty(subClass, "prototype", { writable: false });
if (superClass) _setPrototypeOf(subClass, superClass);
}
// 設定原型 setPrototypeOf
function _setPrototypeOf(o, p) {}
function _createSuper(Derived) {
var hasNativeReflectConstruct = _isNativeReflectConstruct();
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError(
"Derived constructors may only return object or undefined"
);
}
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;
}
// 是否支援 Reflect.construct
function _isNativeReflectConstruct() {}
// 獲取原型 getPrototypeOf
function _getPrototypeOf(o) {}
// 定義屬性
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
// 給prototype設定屬性 / 設定static屬性 / 禁止修改prototype
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", { writable: false });
return Constructor;
}
// 檢查 <不能將類作為函式呼叫>
function _classCallCheck(instance, Constructor) {}
// 設定屬性
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
} else {
obj[key] = value;
}
return obj;
}
var A = /*#__PURE__*/ _createClass(function A(aAge) {
_classCallCheck(this, A);
_defineProperty(this, "aName", "A");
this.aAge = aAge;
});
_defineProperty(A, "aStatic", "aStatic");
var B = /*#__PURE__*/ (function (_A) {
_inherits(B, _A);
var _super = _createSuper(B);
function B(bAge) {
var _this;
_classCallCheck(this, B);
_this = _super.call(this);
_defineProperty(_assertThisInitialized(_this), "bName", "b");
_this.bAge = bAge;
return _this;
}
return _createClass(B);
})(A);
_defineProperty(B, "bStatic", "bStatic");
var b = new B();
流程圖如下:
第一步會執行到這一行:
var A = /*#__PURE__*/ _createClass(function A(aAge) {
進入_createClass, 執行結束後返回處理過的 function A
- 給建構函式的原型設定屬性(原型屬性)
- 給建構函式本身設定屬性(靜態屬性)
- 禁止修改 建構函式的prototype
- 最後返回建構函式本身
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
Object.defineProperty(Constructor, "prototype", { writable: false });
return Constructor;
}
第二步執行:
_defineProperty(A, "aStatic", 'aStatic');
在這裡給A設定aStatic=aStatic.
當key在obj中存在時,修改它的value,並且設定為可列舉,可刪除,可修改
否則在obj中新增value.
// 設定屬性
function _defineProperty(obj, key, value) {
if (key in obj) {
// 修改
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true,
});
} else {
// 新增
obj[key] = value;
}
return obj;
}
第三部執行
var B = /*#__PURE__*/ (function (_A) {
這裡實現了原型繼承和方法繼承
_inherits(B, _A);
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: { value: subClass, writable: true, configurable: true },
});
這裡可以拆分成3部分
- Object.create(superClass && superClass.prototype);
Object.create()方法建立一個新物件,使用現有的物件來提供新建立的物件的__proto__
也就是說這裡生成了一個空物件{},空物件的__proto__是父類的.prototype.
也就是{}.__proto__ = { constructor: f A() }
- { constructor: { value: subClass, writable: true, configurable: true } }
如果該引數被指定且不為 undefined,將為新建立的物件新增指定的屬性值和對應的屬性描述符。
這裡給上面建立的空物件新增constructor屬性,值是f B(),並且設定constructor可修改/刪除,不可被列舉
就變成了這樣{ constructor: f B() }.__proto__ = { constructor: f A() }
- subClass.prototype =
這裡給B設定原型
相當於B.prototype = { constructor: f B() }.__proto__ = { constructor: f A() }
到這裡,原型繼承就實現成功了.
Object.defineProperty(subClass, "prototype", { writable: false });
設定B的prototype不可寫
if (superClass) _setPrototypeOf(subClass, superClass);
這裡實現了方法的繼承,B.__proto__ = A
function的寄生組合繼承是沒有上面一步的.只有class extends才有.
var _super = _createSuper(B);
判斷了環境是否支援Reflect.construct,返回_createSuperInternal閉包給_super變數
return _createClass(B);
同上 _createClass A
_defineProperty(B, "bStatic", "bStatic");
同上
第四步執行 new
var b = new B();
先執行 function B(bAge) {
裡面的內容
檢查是否為function _classCallCheck(this, B);
呼叫上面的_super函式, _this = _super.call(this);
,執行 _createSuperInternal
var Super = _getPrototypeOf(Derived),
result;
if (hasNativeReflectConstruct) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
通過 Reflect.construct
或者 Super.apply
得到例項物件.接下來將 this(也就是f B())
和 result
傳遞給 _possibleConstructorReturn
function _possibleConstructorReturn(self, call) {
if (call && (_typeof(call) === "object" || typeof call === "function")) {
return call;
} else if (call !== void 0) {
throw new TypeError(
"Derived constructors may only return object or undefined"
);
}
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;
}
result
有值,並且是object
或者function
時返回result
result
是基本型別時報錯- 否則返回B物件
_defineProperty(_assertThisInitialized(_this), "bName", "b");
給B物件設定class中定義好的屬性_this.bAge = bAge;
執行constructor
中的this.bAge = bAge
返回B物件return _this;