扩展-babel 对类的转换
我们直接看源代码,写了一个类,然后在 babel 官网在线进行转换,分析转换结果。
js
class A {
prop1 = 1;
method2 = (...args) => {
console.log(args);
};
constructor(b = 2) {
this.prop2 = b;
}
method1() {
console.log("method1");
}
static method3() {
console.log("method3", this);
}
static method4 = () => {
console.log("method4", this);
};
}
js
"use strict";
function _instanceof(left, right) {
//ES6的判断实例方式,因为ES6必须是使用new来创建实例。
//每一个class都有一个Symbol.hasInstance函数,用来判断是否有实例
if (
right != null &&
typeof Symbol !== "undefined" &&
right[Symbol.hasInstance]
) {
return !!right[Symbol.hasInstance](left);
} else {
//es6的判断实例方法
return left instanceof right;
}
}
function _classCallCheck(instance, Constructor) {
//判断instance 是不是Constructor的实例
if (!_instanceof(instance, Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
//props: [{key:"xxx", value:"xxxxxx"}, {key:"ccc", value:function(){}}]
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;
//这段函数最重要的就是这句话,以上的都是在构造descriptor描述符。
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return 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 =
//该立即执行函数的返回结果,应该是一个构造函数A
(function () {
//构造函数A,对应类中的constructor
function A() {
//转换:构造函数的参数默认值
var b =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
//类调用检查
_classCallCheck(this, A);
//定义一个属性:给this定义一个属性prop1,赋值为1,类似于 this.prop1 = 1;
_defineProperty(this, "prop1", 1);
//将箭头函数方法,作为普通属性定义,箭头函数方法并不在原型上
//这个函数是为了处理剩余参数,本质就是将argumets伪数组转换为真数组
_defineProperty(this, "method2", function () {
for (
var _len = arguments.length, args = new Array(_len), _key = 0;
_key < _len;
_key++
) {
args[_key] = arguments[_key];
}
console.log(args);
});
this.prop2 = b;
}
//为构造函数A,定义原型方法,以及静态方法
_createClass(
A,
[
{
key: "method1",
value: function method1() {
console.log("method1");
},
},
],
[
{
key: "method3",
value: function method3() {
console.log("method3", this);
},
},
]
);
return A;
})();
_defineProperty(A, "method4", function () {
console.log("method4", A);
});
心得
读代码的时候应当先找准关键点,从关键点入手,先读整体,然后再读细节。把握整体思想步骤,再深入到每一个函数的细节中去。抽丝剥茧。
ES6 中的 class 必须使用 new 来创建实例,且每一个 class 都有一个 Symbol.hasInstance()函数
箭头函数实际上属于类的属性,而不是原型上的方法。