前言
已经有很多文章指出 enum
语法的各种缺陷了,但是在日常使用时,大家可能并不会碰到这类问题,而 enum
又有着一些便利,所以一些呼吁禁用 enum
的观点并不能得到重视。
直到我们发现另一个严重问题后,我觉得应该再强调一遍这个事情。
enum
不支持 Tree-Shaking
前段时间有同事说没有用到的 enum
定义被打到了包里,我当时觉得这不太可能,编译成 JS 就是一个普通的变量而已,怎么可能不被 Tree-Shaking ?
但是经过实验,我发现这玩意儿确实无法 Tree-Shaking 。查看编译结果,我发现 enum
声明并不会简单的转义成一个变量声明。我们来看一个例子:
enum T {
A,
B,
C
}
上面这段代码会被转译成:
"use strict";
var T;
(function (T) {
T[T["A"] = 0] = "A";
T[T["B"] = 1] = "B";
T[T["C"] = 2] = "C";
})(T || (T = {}));
转义后的这段代码里有一个带 副作用 的立即执行函数,这就是无法被 Tree-Shaking 的根本原因。
替换方案
使用 const enum
在这里有人提到使用 const enum
来替换 enum
,这在确实是可行的。
但是需要注意 const enum
在使用上有一些限制。如果使用 babel 转译需要开启 optimizeConstEnums 选项。
使用 union types
就如这篇文章所说,我们可以使用 union types
来替换 enum
的绝大多数使用场景。
另外,从思维上来讲,使用 enum 需要记忆更多的语法规则,而 union types 就像数学运算一样简单。
如果你需要使用 enum 来为你的标志提供别名,那么可能是你或者上游选择了错误的标志,比如使用 'w'
而不是 'week'
表示“周”。
总结
忘记 enum
吧,这会让一切变得简单,包括语法、工具链。