TypeScript真香系列-枚舉
前言
TypeScript真香系列的內(nèi)容將參考中文文檔,但是文中的例子基本不會(huì)和文檔中的例子重復(fù),對(duì)于一些地方也會(huì)深入研究。另外,文中一些例子的結(jié)果都是在代碼沒(méi)有錯(cuò)誤后編譯為JavaScript得到的。如果想實(shí)際看看TypeScript編譯為JavaScript的代碼,可以訪問(wèn)TypeScript的在線編譯地址,動(dòng)手操作,印象更加深刻。
概念
枚舉是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類型集的擴(kuò)充,常被用來(lái)限定在一定范圍內(nèi)取值的場(chǎng)景。在TypeScript中支持?jǐn)?shù)字和字符串的枚舉。我們可以用enum來(lái)實(shí)現(xiàn)。
數(shù)字枚舉
先看看一個(gè)數(shù)字枚舉例子:
enum?Basketballer{?
????Yao,
????Yi,
????Wang
}
Basketballer.Yao;?//0
Basketballer.Yi;??//1
Basketballer.Wang;??//2
我們也可以這樣,下面這個(gè)方法被稱為反向映射,即通過(guò)值來(lái)訪問(wèn)鍵:
Basketballer[0];?//"Yao"
Basketballer[1];?//"Yi"
Basketballer[2];?//"Wang"
Basketballer[3];?//undefined
上面的例子,我們沒(méi)有對(duì)Yao或者其它成員進(jìn)行初始化,如果我們進(jìn)行初始化:
enum?Basketballer{?
????Yao?=?1,
????Yi,
????Wang
}
Basketballer.Yao;?//1
Basketballer.Yi;??//2
Basketballer.Wang;??//3
Basketballer[1];??//"Yao"
Basketballer[2];??//"Yi"
Basketballer[3];??//"Wang"
從上面可以看出,如果一個(gè)成員設(shè)了一個(gè)值,那么后面相應(yīng)的值都會(huì)遞增。但是要注意的是,如果沒(méi)有什么特殊的目的的話,還是不要對(duì)多個(gè)成員進(jìn)行手動(dòng)賦值。因?yàn)橛袝r(shí)候可能會(huì)導(dǎo)致一些問(wèn)題:
enum?Basketballer{?
????Yao?=?1,
????Yi,
????Wang?=?2,
????Zhu,
????Zhou,
}
Basketballer[2];?//"Wang"
Basketballer.Yi;?//2
一個(gè)枚舉的簡(jiǎn)單應(yīng)用:
enum?Basketballer{?
????Yao?=?1,
????Yi,
????Wang,
????Zhu,
????Zhou,
}
function?one(arg:?Basketballer):?string{
????let?num?=?arg;
????switch?(num)?{
????????case?1:
????????????return?Basketballer[num]?+?"第一人";
????????case?2:
????????????return?Basketballer[num]?+?"第二人";
????????case?3:
????????????return?Basketballer[num]?+?"第二人";
????????default:
????????????return?"籃球";
????}
}
one(1);?//"Yao第一人"
one(6);?//?"籃球人"
one("1");?//錯(cuò)誤,“1”類型的參數(shù)不能分配給Basketballer
在數(shù)字枚舉中,我們?cè)诙x枚舉成員值的時(shí)候,可以是常量,也可以是計(jì)算出來(lái)的:
枚舉成員值為常量
1、枚舉的第一個(gè)成員且沒(méi)有初始化:
enum?Basketballer{?
????Yao
}
Basketballer.Yao;?//0
2、不帶初始化器并且它之前的成員是一個(gè)數(shù)字常量:
enum?Basketballer1{?
????Yao,??//0
????Yi,???//1
????Wang??//2?
}
enum?Basketballer2{?
????Yao?=?1,??//1
????Yi,???????//2
????Wang?????//3?
}
3、枚舉成員使用常量枚舉表達(dá)式初始化。當(dāng)下面條件滿足其中之一,就是一個(gè)常量枚舉表達(dá)式:一個(gè)枚舉表達(dá)式字面量(主要是字符串字面量或數(shù)字字面量)
enum?Man{?a?=?1}
一個(gè)對(duì)之前定義的常量枚舉成員的引用(可以是在不同的枚舉類型中定義的)
enum?Man{?a?=?1,?b?=?2*a}
帶括號(hào)的常量枚舉表達(dá)式
enum?Man{?a?=?1,?b?=?2*(a?+1)}
一元運(yùn)算符 +, -, ~其中之一應(yīng)用在了常量枚舉表達(dá)式
enum?Man{?a?=?1,?b=?~a}
常量枚舉表達(dá)式做為二元運(yùn)算符 +, -, *, /, %, <<, >>, >>>, &, |, ^的操作對(duì)象。若常數(shù)枚舉表達(dá)式求值后為 NaN或 Infinity,則會(huì)在編譯階段報(bào)錯(cuò)。
enum?Man{?a?=?1?<2}
枚舉成員值為計(jì)算值
除開上面所舉的所有枚舉成員都被當(dāng)作是需要計(jì)算出來(lái)的值:
enum?Man{?a?=?"abc".length?}
字符串枚舉
字符串枚舉中沒(méi)有自增的特性,我們?cè)诔跏蓟臅r(shí)候必須給每一個(gè)成員都設(shè)字符串。
enum?Basketballer{?
????Yao?=?"籃協(xié)主席",
????Yi?=?"牌面",
????Wang?=?"老大哥",
}
Basketballer.Yao;?//"籃協(xié)主席"
但是字符串枚舉沒(méi)有反向映射:
Basketballer["籃協(xié)主席"];?//?錯(cuò)誤
異構(gòu)枚舉
異構(gòu)枚舉相當(dāng)于數(shù)字枚舉和字符串枚舉的結(jié)合體,但是官方文檔不建議這樣寫。
enum?Basketballer{?
????Yao?=?"籃協(xié)主席",
????Yi?=?1,
}
const 枚舉
我們可以通過(guò)const修飾符來(lái)強(qiáng)調(diào)當(dāng)前枚舉類型,const枚舉只能使用使用常量枚舉表達(dá)式,而且會(huì)在編譯階段被刪除。我們可以用const enum來(lái)定義:
const?enum?Man?{
????A,
????B,
????C,
????D
}
let?man?=?[Man.A,?Man.B,?Man.C,?Man.D];
console.log(man);?//?[0,?1,?2,?3]
讓我們看看編譯結(jié)果:
let?man?=?[0?/*?A?*/,?1?/*?B?*/,?2?/*?C?*/,?3?/*?D?*/];
console.log(man);?//?[0,?1,?2,?3]
外部枚舉
外部枚舉用來(lái)描述已經(jīng)存在的枚舉類型的形狀,可以用declare enum來(lái)定義:
declare?enum?Man?{
????A,
????B,
????C,
????D
}
let?man?=?[Man.A,?Man.B,?Man.C,?Man.D];
讓我們看看編譯結(jié)果:
let?man?=?[Man.A,?Man.B,?Man.C,?Man.D];
參考
https://github.com/zhongsp/TypeScript https://github.com/jkchao/typescript-book-chinese
最后
文中有些地方可能會(huì)加入一些自己的理解,若有不準(zhǔn)確或錯(cuò)誤的地方,歡迎指出~
