溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

TypeScript枚舉的使用方法

發(fā)布時(shí)間:2020-10-30 14:37:15 來(lái)源:億速云 閱讀:301 作者:Leah 欄目:開(kāi)發(fā)技術(shù)

TypeScript枚舉的使用方法?針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

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:禁止在定義之外的位置修改枚舉成員

其實(shí)我們只想表達(dá)某些變量將以含有Red、Green兩個(gè)成員的Color有窮集合作為值域而已,卻要寫(xiě)這么多語(yǔ)義無(wú)關(guān)的代碼(嚴(yán)格遵循“能寫(xiě)hi絕對(duì)不寫(xiě)hello”原則)。而且在一般規(guī)模的項(xiàng)目當(dāng)中,往往不止一個(gè)枚舉類(lèi)型,復(fù)制粘貼確實(shí)可以解決問(wèn)題,但真心不優(yōu)雅。

而TypeScript內(nèi)置枚舉的語(yǔ)言實(shí)現(xiàn)恰恰能解決這個(gè)問(wèn)題。

TypeScript的枚舉和后端的真不一樣

后端的同學(xué)對(duì)枚舉絕對(duì)是不會(huì)陌生的(除非是Pyton/Nodejs后端的同學(xué)啦),雖然TypeScript是JavaScript的超集,但最終需要編譯為JavaScript代碼,并且要兼容現(xiàn)有JavaScript庫(kù),所以確實(shí)無(wú)法和后端的枚舉類(lèi)型一模一樣。
所以我還是建議大家運(yùn)用空杯心理,重頭理解TypeScript的枚舉類(lèi)型,將過(guò)去的知識(shí)作為助燃劑,而不是圍欄更適宜。

數(shù)字枚舉類(lèi)型和字符串枚舉類(lèi)型

TypeScript官網(wǎng)教程已經(jīng)對(duì)枚舉類(lèi)型進(jìn)行了詳細(xì)的講解說(shuō)明,我認(rèn)為最核心是理解清楚其分為兩大類(lèi):

數(shù)字枚舉類(lèi)型

enum Response {
  No = 0, // 手動(dòng)設(shè)置初始化器
  Yes = // 附加默認(rèn)的支持自動(dòng)增長(zhǎng)的初始化器,因此Yes的值為1
}

特性為:
1.1. 枚舉成員附帶默認(rèn)的初始化器;
1.2. 初始化器支持自動(dòng)增長(zhǎng);
1.3. 支持反向映射。(注意:這里是反向映射,而不是通過(guò)值轉(zhuǎn)換為枚舉成員)

字符串枚舉類(lèi)型

enum Color {
 Red = 'Red',
 Green = 'Green',
}

特性為:
1.1. 必須為枚舉成員設(shè)置初始化器;
1.2. 初始化器不支持自動(dòng)增長(zhǎng);
1.3. 不支持反向映射。

而計(jì)算和常量成員其實(shí)就是上述兩種枚舉類(lèi)型中初始化器的細(xì)分特性罷了。

enum讓數(shù)字枚舉類(lèi)型反向映射成為可能

上一節(jié)介紹到數(shù)字枚舉類(lèi)型支持反向映射,但前提是通過(guò)enum定義的數(shù)字枚舉類(lèi)型才支持。那是因?yàn)閑num Respose {No,Yes,}最終會(huì)被編譯為如下JavaScript代碼:

var Response;
(function (Response) {
  Response[Response["No"] = 0] = "No";
  Response[Response["Yes"] = 1] = "Yes";
})(Response || (Response = {}));

那么我們就可以通過(guò)Response[0]反向映射得到"No"。
但對(duì)于字符串枚舉類(lèi)型就沒(méi)有這種好事了,看看enum Color {Red='Red',Green='Green',}編譯出來(lái)的代碼吧

var Color;
(function (Color) {
  Color["Red"] = "Red";
  Color["Green"] = "Green";
})(Color || (Color = {}));

只能說(shuō)非常樸實(shí)無(wú)華,就這樣沒(méi)啥好說(shuō)的,大家在使用時(shí)注意差異就好了。

const enum高效的編譯時(shí)內(nèi)聯(lián)

官方文檔明確寫(xiě)出“大多數(shù)情況下,枚舉是十分有效的方案。 然而在某些情況下需求很?chē)?yán)格。 為了避免在額外生成的代碼上的開(kāi)銷(xiāo)和額外的非直接的對(duì)枚舉成員的訪(fǎng)問(wèn),我們可以使用 const枚舉”,那是為什么呢?
那是因?yàn)橥ㄟ^(guò)const enum定義的編譯時(shí)枚舉類(lèi)型,效果和通過(guò)C/C++的#define定義常量沒(méi)實(shí)質(zhì)區(qū)別。說(shuō)白了就是假如僅僅通過(guò)通過(guò)const enum定義了枚舉類(lèi)型而沒(méi)有其它地方調(diào)用,這段代碼將在編譯時(shí)被直接抹掉。
當(dāng)其它地方調(diào)用該枚舉類(lèi)型時(shí),將直接把枚舉類(lèi)型成員的值內(nèi)聯(lián)到使用處,如下:

const enum Response {
  No,
  Yes,
}

console.log(Response.NO, Response.Yes)

編譯后成為console.log(0, 1),運(yùn)行效果自然只能比enum定義的好。

什么時(shí)候用enum?又在什么場(chǎng)景下用const enum呢?

先說(shuō)說(shuō)結(jié)論:

使用enum的場(chǎng)景:
1.1. 需要使用反向映射時(shí);
1.2. 需要編譯后的JavaScript代碼保留對(duì)象.屬性或?qū)ο骩屬性]形式時(shí)。

使用const enum的場(chǎng)景:能不用enum時(shí)就用const enum(哈哈!)
使用enum的場(chǎng)景中的第一條還很好理解,但第二條是啥回事呢?我這里有個(gè)真實(shí)發(fā)生的示例,可以讓大家更好的理解:
背景:為Photoshop的ExtendScript編寫(xiě)類(lèi)型聲明。
需求:DialogModes.NO在ExtendScript中返回值為DialogModes.No本身,編譯后的JavaScript中必須保留DialogModes.NO的代碼形式。

那么又為何鼓勵(lì)大家能用const enum時(shí)就用const enum呢?
這是TypeScript為大家特意準(zhǔn)備的編譯時(shí)優(yōu)化方式,好東西為啥不用呢?編譯時(shí)優(yōu)化難道不香嗎?

外部枚舉declare enum的作用?

所謂外部枚舉,即使我們?yōu)榱嗽赥ypeScript開(kāi)發(fā)環(huán)境下,更好地使用某些已采用JavaScript編寫(xiě)的庫(kù),而被迫為其編寫(xiě)的枚舉類(lèi)型聲明。
如ExtendScript標(biāo)準(zhǔn)庫(kù)存在枚舉DialogModes.NO,DialogModes.YES,DialogModes.ALL。于是在.d.ts文件中編寫(xiě)如下外部枚舉類(lèi)型聲明

declare enum DialogModes {
  NO,
  YES,
  ALL,
}

關(guān)于TypeScript枚舉的使用方法問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI