TypeScript入门教程 之 枚举 Enums
TypeScript入门教程 之 枚举 Enums
枚举是一种组织相关值集合的方法。许多其他编程语言(C / C#/ Java)具有
enum
数据类型,而JavaScript没有。但是,TypeScript可以。这是TypeScript枚举的示例定义:
enum CardSuit {Clubs,Diamonds,Hearts,Spades }// Sample usage var card = CardSuit.Clubs;// Safety card = "not a member of card suit"; // Error : string is not assignable to type `CardSuit`
这些枚举值是number
s,因此从此以后我将它们称为Number Enums。
数字枚举和数字
TypeScript枚举基于数字。这意味着可以将数字分配给枚举的实例,与兼容的其他任何事物也可以赋值number
。
enum Color {Red,Green,Blue } var col = Color.Red; col = 0; // Effectively same as Color.Red
数字枚举和字符串
在进一步研究枚举之前,让我们看一下它生成的JavaScript,这里是一个示例TypeScript:
enum Tristate {False,True,Unknown }
生成以下JavaScript:
var Tristate; (function (Tristate) {Tristate[Tristate["False"] = 0] = "False";Tristate[Tristate["True"] = 1] = "True";Tristate[Tristate["Unknown"] = 2] = "Unknown"; })(Tristate || (Tristate = {}));
让我们专注于线上Tristate[Tristate["False"] = 0] = "False";
。在其中Tristate["False"] = 0
应具有自我解释性,即将变量"False"
成员设置Tristate
为0
。请注意,在JavaScript中,赋值运算符返回分配的值(在本例中为0
)。因此,JavaScript运行时执行的下一件事是Tristate[0] = "False"
。这意味着您可以使用该Tristate
变量将枚举的字符串版本转换为数字,或者将枚举的数字版本转换为字符串。如下所示:
enum Tristate {False,True,Unknown } console.log(Tristate[0]); // "False" console.log(Tristate["False"]); // 0 console.log(Tristate[Tristate.False]); // "False" because `Tristate.False == 0`
更改与数字枚举关联的数字
默认情况下,枚举是0
基础,然后每个后续值自动加1。例如,考虑以下内容:
enum Color {Red, // 0Green, // 1Blue // 2 }
但是,可以通过专门分配给任何枚举成员来更改与该枚举成员关联的数字。如下所示,我们从3开始并从那里开始递增:
enum Color {DarkRed = 3, // 3DarkGreen, // 4DarkBlue // 5 }
提示:我通常使用来初始化第一个枚举,
= 1
因为它允许我对枚举值进行安全的真实检查。
数字枚举作为标志
枚举的一种出色用法是能够将枚举用作Flags
。标志允许您检查一组条件中的某个条件是否为真。考虑以下示例,其中我们具有一组有关动物的属性:
enum AnimalFlags {None = 0,HasClaws = 1 << 0,CanFly = 1 << 1,EatsFish = 1 << 2,Endangered = 1 << 3 }
这里我们使用左移操作符来移动1
周围位的一定水平拿出按位不相交的数字0001
,0010
,0100
和1000
(这些都是小数1
,2
,4
,8
如果你很好奇)。当使用标志时,按位运算符|
(or)/ &
(and)/ ~
(not)是您最好的朋友,并在下面进行演示:
enum AnimalFlags {None = 0,HasClaws = 1 << 0,CanFly = 1 << 1, } type Animal = {flags: AnimalFlags }function printAnimalAbilities(animal: Animal) {var animalFlags = animal.flags;if (animalFlags & AnimalFlags.HasClaws) {console.log('animal has claws');}if (animalFlags & AnimalFlags.CanFly) {console.log('animal can fly');}if (animalFlags == AnimalFlags.None) {console.log('nothing');} }let animal: Animal = { flags: AnimalFlags.None }; printAnimalAbilities(animal); // nothing animal.flags |= AnimalFlags.HasClaws; printAnimalAbilities(animal); // animal has claws animal.flags &= ~AnimalFlags.HasClaws; printAnimalAbilities(animal); // nothing animal.flags |= AnimalFlags.HasClaws | AnimalFlags.CanFly; printAnimalAbilities(animal); // animal has claws, animal can fly
这里:
- 我们曾经
|=
添加标志 &=
和~
清除标志的组合|
组合标志
注意:您可以组合标志以在枚举定义内创建方便的快捷方式,例如
EndangeredFlyingClawedFishEating
:
enum AnimalFlags {None = 0,HasClaws = 1 << 0,CanFly = 1 << 1,EatsFish = 1 << 2,Endangered = 1 << 3,EndangeredFlyingClawedFishEating = HasClaws | CanFly | EatsFish | Endangered, }
字符串枚举
我们只看了成员值为number
s的枚举。实际上,您也可以让枚举成员具有字符串值。例如
export enum EvidenceTypeEnum {UNKNOWN = '',PASSPORT_VISA = 'passport_visa',PASSPORT = 'passport',SIGHTED_STUDENT_CARD = 'sighted_tertiary_edu_id',SIGHTED_KEYPASS_CARD = 'sighted_keypass_card',SIGHTED_PROOF_OF_AGE_CARD = 'sighted_proof_of_age_card', }
这些可以提供有意义的/可调试的字符串值,因此更易于处理和调试。
您可以使用这些值进行简单的字符串比较。例如
// Where `someStringFromBackend` will be '' | 'passport_visa' | 'passport' ... etc. const value = someStringFromBackend as EvidenceTypeEnum; // Sample use in code if (value === EvidenceTypeEnum.PASSPORT){console.log('You provided a passport');console.log(value); // `passport` }
常量枚举
如果您具有如下的枚举定义:
enum Tristate {False,True,Unknown }var lie = Tristate.False;
该行var lie = Tristate.False
被编译为JavaScript var lie = Tristate.False
(是的,输出与输入相同)。这意味着,在执行运行时将需要查找Tristate
,然后Tristate.False
。要提高性能,您可以将标记enum
为const enum
。如下所示:
const enum Tristate {False,True,Unknown }var lie = Tristate.False;
生成JavaScript:
var Ile = 0 ;
即编译器:
- 内联枚举(任何用途
0
,而不是Tristate.False
)。 Tristate
因为内联用法,所以不会为该枚举定义生成任何JavaScript(运行时没有变量)。
常量枚举preserveConstEnums
内联具有明显的性能优势。Tristate
运行时没有变量的事实仅仅是编译器通过不生成运行时实际未使用的JavaScript来帮助您。但是,您可能希望编译器仍然为诸如数字到字符串或字符串到数字的查找之类的东西生成枚举定义的JavaScript版本。在这种情况下,您可以使用编译器标志--preserveConstEnums
,它仍将生成var Tristate
定义,以便您可以在运行时使用Tristate["False"]
或Tristate[0]
手动进行定义。这不会以任何方式影响内联。
带有静态函数的枚举
您可以使用声明enum
+ namespace
合并将静态方法添加到枚举。下面演示了一个isBusinessDay
向枚举添加静态成员的示例Weekday
:
enum Weekday {Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday } namespace Weekday {export function isBusinessDay(day: Weekday) {switch (day) {case Weekday.Saturday:case Weekday.Sunday:return false;default:return true;}} }const mon = Weekday.Monday; const sun = Weekday.Sunday; console.log(Weekday.isBusinessDay(mon)); // true console.log(Weekday.isBusinessDay(sun)); // false
枚举是开放式的
注意:仅当不使用模块时,开放式枚举才有意义。您应该使用模块。因此,本节最后。
这是为再次显示的枚举生成的JavaScript:
var Tristate; (function (Tristate) {Tristate[Tristate["False"] = 0] = "False";Tristate[Tristate["True"] = 1] = "True";Tristate[Tristate["Unknown"] = 2] = "Unknown"; })(Tristate || (Tristate = {}));
我们已经解释了该Tristate[Tristate["False"] = 0] = "False";
部分。现在注意周围的代码,(function (Tristate) { /*code here */ })(Tristate || (Tristate = {}));
特别是该(Tristate || (Tristate = {}));
部分。这基本上捕获了一个局部变量TriState
,该局部变量将指向一个已定义的Tristate
值或使用一个新的空{}
对象对其进行初始化。
这意味着您可以跨多个文件拆分(和扩展)枚举定义。例如,下面我们将的定义Color
分为两个块
enum Color {Red,Green,Blue }enum Color {DarkRed = 3,DarkGreen,DarkBlue }
请注意,您应该(在这里重新初始化第一个成员DarkRed = 3
在枚举的延续)来获取生成的代码从以前的定义不会破坏值(即0
,1
...等等的值)。无论如何,TypeScript都会警告您(错误消息In an enum with multiple declarations, only one declaration can omit an initializer for its first enum element.
)。
翻译来源:https://gitee.com/yunwisdoms/typescript-book/blob/master/docs/enums.md
TypeScript入门教程 之 枚举 Enums相关推荐
- 我写的第一本书《TypeScript 入门教程》
阅读原文 持续了大半年的学习和写作,在今天终于告一段落了. 写书之旅 最初有写书的想法,是刚加入微软的时候. 由于工作中需要重度使用 TypeScript,所以我花了几天的时间研读了好几遍官方手册和中 ...
- TypeScript入门教程 之 classes-emit
TypeScript入门教程 之 classes-emit What's up with the IIFE 为该类生成的js可能是: function Point(x, y) {this.x = x; ...
- TypeScript入门教程 之 箭头函数
TypeScript入门教程 之 箭头函数 亲切地称为粗箭头(因为->是细箭头并且=>是粗箭头),也被称为lambda函数(由于其他语言).另一个常用功能是胖箭头功能()=>some ...
- TypeScript入门教程 之 类/抽象类/构造器/Getter/Setter
TypeScript入门教程 之 类/抽象类/构造器/Getter/Setter 将JavaScript中的类作为头等项很重要的原因是: 类提供了有用的结构抽象 为开发人员提供一种一致的方式来使用类, ...
- TypeScript入门教程 之 const
TypeScript入门教程 之 const const是ES6 / TypeScript提供的非常受欢迎的功能.它使您可以与变量保持不变.从文档以及运行时的角度来看,这都是很好的.要使用const只 ...
- TypeScript入门教程 之 解构
TypeScript入门教程 之 解构 TypeScript支持以下形式的解构(以解构的名义命名,即分解结构): 对象分解 阵列解构 人们很容易将解构视为结构的逆.JavaScript中的结构化方法是 ...
- TypeScript入门教程 之 for ... of 与 for ... in
TypeScript入门教程 之 for ... of 与 for ... in 新手JavaScript开发人员经常遇到的错误是,for...in数组不会遍历数组项.相反,它迭代传入的对象的键.下面 ...
- TypeScript入门教程 之 生成器函数
TypeScript入门教程 之 生成器函数 生成器函数 function *是用于创建生成器函数的语法.调用generator函数将返回一个generator对象.发电机对象如下刚刚所述迭代器接口( ...
- 原创 TypeScript入门教程 之 迭代器
原创 TypeScript入门教程 之 迭代器 Iterator Iterator本身不是TypeScript或ES6功能,Iterator是面向对象的编程语言所通用的行为设计模式.通常,它是一个实现 ...
最新文章
- linux共享内存通信方式,linux下进程通信方式--共享内存
- 常见Java面试题 – 第二部分:equals与==
- 7-48 银行排队问题之单窗口“夹塞”版 (30 分)(思路和详解+map做法)来呀Baby!
- Winform开发框架中工作流模块的动态处理
- SPQuery如何消除重复记录(实现联动性)
- 编译原理教程_3 词法分析
- 分享119个Android手机应用源代码总有一个是你想要的
- NTKO OFFICE控件帮助文档部分汇总
- 3分钟下载好网易云付费音乐
- GPGPU基础(五):使用compute shader进行通用计算及示例
- SVN中clean up的含义
- 判断闰年和平年的程序
- iov_iter结构体
- adb无线连接不上 解决办法
- 【愚公系列】2021年11月 攻防世界-进阶题-MISC-055(肥宅快乐题)
- SSMS证书已被颁发者吊销解决办法
- Facebook 如何存储150亿张、1.5PB的照片
- php录音功能,微信开发之录音功能
- Python爬虫实战:京东拍拍验机(帮你买到最完美的二手iPhone)
- 我发现,英语,是这辈子都躲不过的事儿