TypeScript 枚举(Enum)
本节介绍枚举类型的定义及其使用,需要定义一组相同主题的常量数据时,应该立即想到枚举类型。在学习过程中,需要注意枚举类型的正向映射和反向映射,可以通过编译后的 JavaScript 源码进行分析,为什么可以进行反向映射。
1. xx解释
使用枚举我们可以定义一些带名字的常量。TypeScript 支持数字的和基于字符串的枚举。
2. 定义及使用场景
枚举类型弥补了 JavaScript 的设计不足,很多语言都拥有枚举类型。
当我们需要一组相同主题下的数据时,枚举类型就很有用了。
enum Direction { Up, Down, Left, Right }
enum Months { Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec }
enum Size { big = '大', medium = '中', small = '小' }
enum Agency { province = 1, city = 2, district = 3 }
代码中通过枚举类型分别声明了:不同的 方向
,一年内不同的 月份
,一个商品的不同 尺寸属性
,经销商的不同 级别
,这样的一组常量数据,是在一个相同主题下的不同表示。
3. 数字枚举与字符串枚举
声明一个枚举类型,如果没有赋值,它们的值默认为数字类型且从 0 开始累加:
enum Months {
Jan,
Feb,
Mar,
Apr
}
Months.Jan === 0
Months.Feb === 1
Months.Mar === 2
Months.Apr === 3
enum Months {
Jan = 1,
Feb,
Mar,
Apr
}
Months.Jan === 1
Months.Feb === 2
Months.Mar === 3
Months.Apr === 4
第 3 行,从属性 Jan
被赋值为 1
开始,后续的属性值依次累加。
代码解释: 枚举的取值,有 TokenType.ACCESS
和 TokenType['ACCESS']
这两种不同的写法,效果是相同的。
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
4. 计算常量成员
5. 反向映射
所谓的反向映射就是指枚举的取值,不但可以正向的 Months.Jan
这样取值,也可以反向的 Months[1]
这样取值。
enum Months {
Jan = 1,
Feb,
Mar,
Apr
}
将上面的代码进行编译,查看编译后的 JavaScript 代码:
'use strict'
var Months;
(function (Months) {
Months[Months['Jan'] = 1] = 'Jan'
Months[Months['Feb'] = 2] = 'Feb'
Months[Months['Mar'] = 3] = 'Mar'
Months[Months['Apr'] = 4] = 'Apr'
})(Months || (Months = {}))
console.log(Months.Mar === 3)
console.log(Months[3])
console.log(Months.Mar === 3)
console.log(Months[3] === 'Mar')
- 字符串枚举成员不会生成反向映射。
- 枚举类型被编译成一个对象,它包含了正向映射( name -> value)和反向映射( value -> name)。
6. const 枚举
enum Months {
Jan = 1,
Feb,
Mar,
Apr
}
const month = Months.Mar
'use strict'
const month = 3
发现枚举类型应该编译出的对象没有了,只剩下 month
常量。这就是使用 const
关键字声明枚举的作用。因为变量 month
已经使用过枚举类型,在编译阶段 TypeScript 就将枚举类型抹去,这也是性能提升的一种方案。
7. 枚举合并
'use strict'
var Months;
(function (Months) {
Months[Months['Jan'] = 1] = 'Jan'
Months[Months['Feb'] = 2] = 'Feb'
Months[Months['Mar'] = 3] = 'Mar'
Months[Months['Apr'] = 4] = 'Apr'
})(Months || (Months = {}));
(function (Months) {
Months[Months['May'] = 5] = 'May'
Months[Months['Jun'] = 6] = 'Jun'
})(Months || (Months = {}))
console.log(Months.Apr)
console.log(Months.Jun)
8. 小结
- 通过关键字
enum
来声明枚举类型。
- TypeScript 仅支持基于数字和字符串的枚举。
- 通过枚举类型编译后的结果,了解到其本质上就是 JavaScript 对象。