Eson Wong's Blog

编程笔记,投资记录, 读书总结, 生活心得

0%

Babel 的 Class 的转换

babel class 转换

ES6 加入了 Class 的语法,Class 的大部分功能 ES5 都可以做到,我们可以把 class 看作是一个语法糖。本篇文章我们一步步来看看 Babel 是怎么把 class 转换成 ES5 语法的。

观察方发

在 Babel 的官网上有一个 Try it out 的网页可以方便的看到编译后的代码。我们要看转换成 ES5 的语法,我们在 ENV PRESET 取消勾选 Enabled.

空类

我们先来看看一个没有属性、方法和构造函数的类会被转换成什么。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class A {}
new A();

// ------------ 转换 ------------------ //

("use strict");

function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}

var A = function A() {
_classCallCheck(this, A);
};

new A();

可以看到 class A{} 被转化成了一个函数 A。除此之外还生成了一个函数 _classCallCheck 检测 A 是否用 new 关键只来调用的。

构造函数

我们来添加一个 constructor 方法到 class A{}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class A {
constructor() {
this.propA = "A";
}
}

// ------------ 转换 ------------------ //

// 略:function _classCallCheck(){}
var A = function A() {
_classCallCheck(this, A);

this.propA = "A";
};

转换后 constructor 方法内的代码内容被简单的搬到 function A(){} 内部。

属性

类的公有属性声明仍然处于实验性功能第 3 阶段。开启此特性我们要在 PULGINS 里添加 @babel/plugin-proposal-class-properties 插件。
添加一个属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
constructor() {
this.propA = "A";
}
propB = 1;
}

// ------------ 转换 ------------------ //

// 略:function _classCallCheck(){}
var A = function A() {
_classCallCheck(this, A);
this.propB = 1;
this.propA = "A";
};

公有属性 propB 转换成 fuxntion A(){} 函数内的的 this.propB

私有属性同样还没通过标准,需要添加 @babel/plugin-proposal-class-properties 插件来转换。

静态方法

添加一个方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
class A {
method() {
console.log("method");
}
}
// ------------ 转换 ------------------ //

// 略:function _classCallCheck(){}
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);
}
}

function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}

var A = (function () {
function A() {
_classCallCheck(this, A);
}

_createClass(A, null, [
{
key: "method",
value: function staticMethod() {
console.log("method");
},
},
]);

return A;
})();

Bable 使用闭包函数并创建了一个 _createClass 函数来给 function A(){} 添加方法。

参考

欢迎关注我的其它发布渠道