enum
类型是对JavaScript标准数据类型的一个补充。
在运行环境下编译成对象, 可用属性名索引, 也可用属性值索引。而其实现原理为:反向映射 (如下例)
-
数字枚举
enum Role { Reporter, // Reporter = 1, 默认情况下,从0开始为元素编号。 也可赋值,后续值递增 Developer, Maintainer, Owner, Guest }
编译准成为如下:
var Role; (function (Role) { Role[Role["Reporter"] = 0] = "Reporter"; Role[Role["Developer"] = 1] = "Developer"; Role[Role["Maintainer"] = 2] = "Maintainer"; Role[Role["Owner"] = 3] = "Owner"; Role[Role["Guest"] = 4] = "Guest"; })(Role || (Role = {}));
-
字符串枚举 :
只有成员的名称被当作的key,未作反向映射
enum Message { Success = '成功!', Fail = '失败!' }
编译准成为如下:
var Message; (function (Message) { Message["Success"] = "u6210u529FuFF01"; Message["Fail"] = "u5931u8D25uFF01"; })(Message || (Message = {}));
-
异构枚举 :
可以混合字符串和数字成员
enum Answer { N, Y = 'Yes' } // 编译结果如下: var Answer; (function (Answer) { Answer[Answer["N"] = 0] = "N"; Answer["Y"] = "Yes"; })(Answer || (Answer = {}));
-
枚举成员(只读的状态):
分为 常量成员 、 计算成员:
enum Char { // const member 为未初始化/对已有枚举成员的引用/常量表达式 (在编译时计算出结果,然后以常量的形式出现在运行环境 a, b = Char.a, c = 1 + 3, // compute member 不会在编译阶段进行计算,而会保留到程序的执行阶段 d = Math.random(), e = '123'.length, } 编译后==》 var Char; (function (Char) { // const member 为未初始化/对已有枚举成员的引用/常量表达式 (在编译时计算出结果,然后以常量的形式出现在运行环境 Char[Char["a"] = 0] = "a"; Char[Char["b"] = 0] = "b"; Char[Char["c"] = 4] = "c"; // compute member 不会在编译阶段进行计算,而会保留到程序的执行阶段 Char[Char["d"] = Math.random()] = "d"; Char[Char["e"] = '123'.length] = "e"; })(Char || (Char = {})); Char.a = 2 // Cannot assign to 'a' because it is a read-only property (只读状态)
-
常量枚举 :
用const定义的枚举为常量枚举,会在编译阶段被移除
场景:当不需要一个对象,而只需要对象的值时,可使用常量枚举。会减少在编译环境上的代码
const enum Month { Jan, Feb, Mar } let month = [Month.Jan, Month.Feb, Month.Mar] 编译后==》 var month = [0 /* Jan */, 1 /* Feb */, 2 /* Mar */];
-
枚举类型:
在某种情况下,枚举和枚举成员都可以作为一种单独的类型存在(枚举成员没有初始值 / 所有成员都为数字枚举 / 所有成员均为字符串枚举)
enum E { a, b } enum F { a = 0, b = 1 } enum G { a = 'apple', b = 'banana'} let e: E = 3 let f: F = 3 e === f This condition will always return 'false' since the types 'E' and 'F' have no overlap// 两种不同种类的枚举是无法比较的 let e1: E.a = 1 let e2: E.b = 2 // e1 === e2 同上 let e3: E.a = 3 e1 === e3 // 相同枚举成员类型,即可比较 let g1: G = G.a | G.b // 字符串枚举 取值只能是 枚举成员的类型 let g2: G.a = G.a // 只能为G.a