您好,登錄后才能下訂單哦!
TypeScript枚舉的使用方法?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
class Color { // tricky:自增枚舉成員值 static counter = null // 枚舉成員 static Red = new Color('Red') static Green = new Color('Green') // 反向映射 static valueOf(value) { for (var name in Color) { if (!(name in Color.prototype) && Color[name].value === value) { return Color[name] } } } constructor(name, value){ if ('counter' in Color);else return this.name = name if (value == null) { if (Color.counter === null) { this.value = Color.counter = 0 } else { this.value = ++Color.counter } } else { this.value = Color.counter = value } } toString() { return `Color.${this.name}` } } delete Color.counter Object.freeze(Color) // tricky:禁止在定義之外的位置修改枚舉成員
其實我們只想表達某些變量將以含有Red、Green兩個成員的Color有窮集合作為值域而已,卻要寫這么多語義無關的代碼(嚴格遵循“能寫hi絕對不寫hello”原則)。而且在一般規模的項目當中,往往不止一個枚舉類型,復制粘貼確實可以解決問題,但真心不優雅。
而TypeScript內置枚舉的語言實現恰恰能解決這個問題。
TypeScript的枚舉和后端的真不一樣
后端的同學對枚舉絕對是不會陌生的(除非是Pyton/Nodejs后端的同學啦),雖然TypeScript是JavaScript的超集,但最終需要編譯為JavaScript代碼,并且要兼容現有JavaScript庫,所以確實無法和后端的枚舉類型一模一樣。
所以我還是建議大家運用空杯心理,重頭理解TypeScript的枚舉類型,將過去的知識作為助燃劑,而不是圍欄更適宜。
數字枚舉類型和字符串枚舉類型
TypeScript官網教程已經對枚舉類型進行了詳細的講解說明,我認為最核心是理解清楚其分為兩大類:
數字枚舉類型
enum Response { No = 0, // 手動設置初始化器 Yes = // 附加默認的支持自動增長的初始化器,因此Yes的值為1 }
特性為:
1.1. 枚舉成員附帶默認的初始化器;
1.2. 初始化器支持自動增長;
1.3. 支持反向映射。(注意:這里是反向映射,而不是通過值轉換為枚舉成員)
字符串枚舉類型
enum Color { Red = 'Red', Green = 'Green', }
特性為:
1.1. 必須為枚舉成員設置初始化器;
1.2. 初始化器不支持自動增長;
1.3. 不支持反向映射。
而計算和常量成員其實就是上述兩種枚舉類型中初始化器的細分特性罷了。
enum讓數字枚舉類型反向映射成為可能
上一節介紹到數字枚舉類型支持反向映射,但前提是通過enum定義的數字枚舉類型才支持。那是因為enum Respose {No,Yes,}最終會被編譯為如下JavaScript代碼:
var Response; (function (Response) { Response[Response["No"] = 0] = "No"; Response[Response["Yes"] = 1] = "Yes"; })(Response || (Response = {}));
那么我們就可以通過Response[0]反向映射得到"No"。
但對于字符串枚舉類型就沒有這種好事了,看看enum Color {Red='Red',Green='Green',}編譯出來的代碼吧
var Color; (function (Color) { Color["Red"] = "Red"; Color["Green"] = "Green"; })(Color || (Color = {}));
只能說非常樸實無華,就這樣沒啥好說的,大家在使用時注意差異就好了。
const enum高效的編譯時內聯
官方文檔明確寫出“大多數情況下,枚舉是十分有效的方案。 然而在某些情況下需求很嚴格。 為了避免在額外生成的代碼上的開銷和額外的非直接的對枚舉成員的訪問,我們可以使用 const枚舉”,那是為什么呢?
那是因為通過const enum定義的編譯時枚舉類型,效果和通過C/C++的#define定義常量沒實質區別。說白了就是假如僅僅通過通過const enum定義了枚舉類型而沒有其它地方調用,這段代碼將在編譯時被直接抹掉。
當其它地方調用該枚舉類型時,將直接把枚舉類型成員的值內聯到使用處,如下:
const enum Response { No, Yes, } console.log(Response.NO, Response.Yes)
編譯后成為console.log(0, 1),運行效果自然只能比enum定義的好。
什么時候用enum?又在什么場景下用const enum呢?
先說說結論:
使用enum的場景:
1.1. 需要使用反向映射時;
1.2. 需要編譯后的JavaScript代碼保留對象.屬性或對象[屬性]形式時。
使用const enum的場景:能不用enum時就用const enum(哈哈!)
使用enum的場景中的第一條還很好理解,但第二條是啥回事呢?我這里有個真實發生的示例,可以讓大家更好的理解:
背景:為Photoshop的ExtendScript編寫類型聲明。
需求:DialogModes.NO在ExtendScript中返回值為DialogModes.No本身,編譯后的JavaScript中必須保留DialogModes.NO的代碼形式。
那么又為何鼓勵大家能用const enum時就用const enum呢?
這是TypeScript為大家特意準備的編譯時優化方式,好東西為啥不用呢?編譯時優化難道不香嗎?
外部枚舉declare enum的作用?
所謂外部枚舉,即使我們為了在TypeScript開發環境下,更好地使用某些已采用JavaScript編寫的庫,而被迫為其編寫的枚舉類型聲明。
如ExtendScript標準庫存在枚舉DialogModes.NO,DialogModes.YES,DialogModes.ALL。于是在.d.ts文件中編寫如下外部枚舉類型聲明
declare enum DialogModes { NO, YES, ALL, }
關于TypeScript枚舉的使用方法問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。