(Class)代码经过babel 编译后结构会发生改变
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed += speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stopped.`);
}
}
// Inherit from Animal
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
var a = new Rabbit('123');
a.hide();
经过编译后的 Class 结构
var Animal = /*#__PURE__*/function () {
"use strict";
function Animal(name) {
_classCallCheck(this, Animal);
this.speed = 0;
this.name = name;
}
_createClass(Animal, [{
key: "run",
value: function run(speed) {
this.speed += speed;
alert("".concat(this.name, " runs with speed ").concat(this.speed, "."));
}
}, {
key: "stop",
value: function stop() {
this.speed = 0;
alert("".concat(this.name, " stopped."));
}
}]);
return Animal;
}(); // Inherit from Animal
var Rabbit = /*#__PURE__*/function (_Animal) {
"use strict";
_inherits(Rabbit, _Animal);
var _super = _createSuper(Rabbit);
function Rabbit() {
_classCallCheck(this, Rabbit);
return _super.apply(this, arguments);
}
_createClass(Rabbit, [{
key: "hide",
value: function hide() {
alert("".concat(this.name, " hides!"));
}
}]);
return Rabbit;
}(Animal);
var a = new Rabbit('123');
a.hide();
实现继承的源码
/**
*
* @param {Function} o 传入一个函数
* @returns {Function|Object} 返回 o 的 __proto__ 父原型链
*/
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
/**
* 设置(o的__proto__)的执向到(p)
* @param {*} o
* @param {*} p
* @returns {Function} o
*/
function _setPrototypeOf(o, p) {
_setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
};
return _setPrototypeOf(o, p);
}
/**
* 重写原型subClass的 constructor,设置 (subClass)的__proto__的执向到(superClass)
* @param {Function} subClass
* @param {Function} superClass
*/
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);
}
/**
* 创建继承的父级
* @param {Function} Derived 传入子函数
* @returns {Function} 返回 Derived.__proto__ 原型元素
*/
function _createSuper(Derived) {
return function _createSuperInternal() {
var Super = _getPrototypeOf(Derived),
result;
result = Super.apply(this, arguments);
return result;
};
}
/**
* 设置(Class)属性
* @param {Function} target
* @param {Array} props
*/
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);
}
}
/**
*
* @param {Function} Constructor
* @param {Array} protoProps
* @param {Array} staticProps
* @returns {Function} Constructor
*/
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var Animal = /*#__PURE__*/function () {
"use strict";
function Animal(name) {
this.speed = 0;
this.name = name;
}
_createClass(Animal, [{
key: "run",
value: function run(speed) {
this.speed += speed;
alert("".concat(this.name, " runs with speed ").concat(this.speed, "."));
}
}, {
key: "stop",
value: function stop() {
this.speed = 0;
alert("".concat(this.name, " stopped."));
}
}]);
return Animal;
}(); // Inherit from Animal
var Rabbit = /*#__PURE__*/function (_Animal) {
"use strict";
_inherits(Rabbit, _Animal);
var _super = _createSuper(Rabbit);
function Rabbit() {
var result = _super.apply(this, arguments);
return result;
}
_createClass(Rabbit, [{
key: "hide",
value: function hide() {
alert("".concat(this.name, " hides!"));
}
}]);
return Rabbit;
}(Animal); // console.dir(Rabbit);
// console.log(Rabbit.__proto__);
var a = new Rabbit('4444');
console.dir(a);
总结大概思路
-
重写原型 prototype和构造器 constructor,设置__proto__的执向到父级
-
重写原型 prototype 和构造器 constructor 后原有的child方法丢失,重新赋值上去。
-
父级的私有数据通过利用 Super.apply(this, arguments);拷贝过来,最后返回。