TypeScript枚举的使用方法

发布时间:2020-10-30 14:37:15 作者:Leah
来源:亿速云 阅读:307

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枚举的使用方法问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

推荐阅读:
  1. 枚举器,快速枚举
  2. java中枚举的原理和使用方法

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

typescript 枚举

上一篇:springboot项目如何导出成war包

下一篇:php-fpm指的是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》