枚举类型
应用:可以将程序中不容易记忆的硬编码或者是再未来中可能改变的常量抽取出来定义为枚举类型,以提高程序的可读性和可维护性。
枚举:一组有名字的常量集合,类似你的电话簿
枚举类型使用
enum关键字声明,主要用来增强代码的可读性和可维护性
数字枚举
// 使用默认初始值
enum Role1 {
Reporter,
Developer,
Maintainer,
Owner,
Guest
}
// 上边的Role一共有五个枚举成员,默认第一个枚举成员的值为0,依次递增
console.log(Role1.Developer) // 1
console.log(Role1.Guest) // 4
// 使用自定义初始值
enum Role2 {
Reporter = 1,
Developer,
Maintainer,
Owner,
Guest
}
// 自定义第一个枚举成员的值为1,依次递增
console.log(Role2.Developer) // 2
console.log(Role2.Guest) // 5
// 直接打印Role
console.log(Role1)
// 发现得到的结果是一个对象
{
0: "Reporter"
1: "Developer"
2: "Maintainer"
3: "Owner"
4: "Guest"
Developer: 1
Guest: 4
Maintainer: 2
Owner: 3
Reporter: 0
}
// 那也就是说数字枚举就既可以通过枚举成员的名字来索引,也可以通过值来索引
console.log(Role1[0]) // Reporter
console.log(Role1.Reporter) // 0 (number型)
// 将ts代码编译后我们可以看到它是这样实现的 这种方法叫做反向映射
var Role1;
(function (Role1) {
Role1[Role1["Reporter"] = 0] = "Reporter"; // 其中Role1["Reporter"] = 0 返回的是0
Role1[Role1["Developer"] = 1] = "Developer";
Role1[Role1["Maintainer"] = 2] = "Maintainer";
Role1[Role1["Owner"] = 3] = "Owner";
Role1[Role1["Guest"] = 4] = "Guest";
})(Role1 || (Role1 = {}));
字符串枚举
// 先定义一个字符串枚举 Message
enum Messgae {
Success = "恭喜你,成功了",
Fail = "对不起,失败了"
}
// 将Message编译后
var Messgae;
(function (Messgae) {
Messgae["Success"] = "\u606D\u559C\u4F60\uFF0C\u6210\u529F\u4E86";
Messgae["Fail"] = "\u5BF9\u4E0D\u8D77\uFF0C\u5931\u8D25\u4E86";
})(Messgae || (Messgae = {}));
// 我们可以发现字符串枚举并没有进行反向映射,只能通过枚举成员的名字来索引
console.log(Messgae.Success) // 恭喜你,成功了
枚举成员
枚举成员的值是一个只读类型,定义过后不能修改。
枚举成员的顺序应该是先常量枚举成员后非常量枚举成员
enum Char {
// const 编译时计算出结果 最后以常量的形式出现在运行时环境
a, // 1.没有初始值的情况
b = Char.a, // 2.对已有成员的引用
c = 1 + 5, // 3.常量的表达式
// computed 需要被计算的枚举成员 一些非常量的表达式 不会在编译阶段计算 会在运行时环境进行计算
d = Math.random(),
e = '123'.length
}
// 编译结果
var Char;
(function (Char) {
// const枚举 编译时计算出结果 最后以常量的形式出现在运行时环境
Char[Char["a"] = 0] = "a";
Char[Char["b"] = 0] = "b";
Char[Char["c"] = 6] = "c";
// computed枚举 一些非常量的表达式 需要被计算的枚举成员 在编译时进行保留 在运行时环境再进行计算
Char[Char["d"] = Math.random()] = "d";
Char[Char["e"] = '123'.length] = "e";
})(Char || (Char = {}));
常量枚举
编译阶段会被移除,编译后没有任何代码
const enum Month {
Jan,
Feb,
Mar
}
let month = [Month.Jan, Month.Feb, Month.Mar]
// 编译后
var month = [0 /* Jan */, 1 /* Feb */, 2 /* Mar */];