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"] = "\u6210\u529F\uFF01"; Message["Fail"] = "\u5931\u8D25\uFF01"; })(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
