告别魔法数字
在以往的开发中往往会出现类似以下的代码
if(status === 1) {
// do something
} else if(status === 2) {
// do something
} else if (status === 3) {
// ...
}
上面代码中的 1,2,3就是所谓的魔法数字,即没有注释的情况下我们很难知道 1,2,3 代表的到底是什么 status。
常量对象
在 javascript 中,我们可以将这些数字维护在一个常量对象中
const STATUS = {
ERROR: 1,
NORMAL: 2,
SUCCESS: 3
}
使用时就可以使用 STATUS.ERROR 来替换掉 1。
这样可以很清晰就分清楚 1,2,3 这些数值对应的是什么含义。同时如果将来 ERROR 不再是 1,我们也只需要维护 STATUS 即可。
Enums
基本使用
而在 TypeScript 中,我们则可以使用枚举类型来维护这些数值。
enum STATUS {
ERROR = 1,
NORMAL,
SUCCESS
}
使用时同样是 STATUS.ERROR 替换掉 1 即可。
关于 enums 的使用文档里描述的已经很清楚,这里不再赘述。
反向映射
值得一提的是 enums 提供了常量对象不具备的反向映射(value->name )。
const STATUS = {
ERROR: 1,
NORMAL: 2,
SUCCESS: 3
}
// 输出:"ERROR"
STATUS[1]
这是因为 ts 将上述的 enums 编译成以下代码
var STATUS;
(function (STATUS) {
STATUS[STATUS["ERROR"] = 1] = "ERROR";
STATUS[STATUS["NORMAL"] = 2] = "NORMAL";
STATUS[STATUS["SUCCESS"] = 3] = "SUCCESS";
})(STATUS || (STATUS = {}));
⚠️ 但如果是字符串枚举成员则不会生成反向映射。
enum STATUS {
ERROR = "1",
NORMAL = "2",
SUCCESS = "3"
}
// 编译后
var STATUS;
(function (STATUS) {
STATUS["ERROR2"] = "1";
STATUS["NORMAL"] = "2";
sSTATUS["SUCCESS"] = "3";
})(STATUS || (STATUS = {}));
并且对于重复定义的枚举类型,将会合并成员:
enum STATUS {
ERROR = 1,
}
enum STATUS {
NORMAL = 2,
}
// 等效于
enum STATUS {
ERROR = 1,
NORMAL = 2,
}
const 枚举
关于枚举,还有一种不是常见的写法
const enum STATUS {
ERROR = 1,
}
即声明前有个关键字 const。
与常规枚举不同的地方在于
- const 枚举不会编译出额外的代码
const enum STATUS {
ERROR = 1,
}
console.log(STATUS.ERROR)
// 最终的编译出的代码不包含 STATUS
console.log(1 /* ERROR */);
- 也正因为编译阶段就会确定下枚举的成员,const 枚举不可以包含计算成员
const geterror = () => 3
const enum STATUS {
// In 'const' enum declarations member initializer must be constant expression.
ERROR = geterror()
}