共计 3732 个字符,预计需要花费 10 分钟才能阅读完成。
前言
什么是枚举,顾名思义咱们看到枚举这个词,脑子里就曾经想到这是一个键值对的模式,就可以看做是咱们 JavaScript
中的 json
对象一样。在 ts 中申明枚举对象的关键字是应用enum
,枚举成员一但定义就不可扭转了。上面来介绍一下 ts 中的枚举对象。
数字枚举
咱们先来说一下 数字枚举
, 高深莫测,一看就晓得数字枚举的成员都是number
类型的。上面咱们来看看创立一个简略的枚举对象吧。
enum device {
phone,
notebook,
desktop
}
console.log(device.phone) // 0
下面的值是phone
0、notebook
1、desktop
2。
只有定义了枚举对象,默认不赋值,那么以后的枚举对象外面第一个的值从 0 开始顺次递增。
看上面栗子
enum device {
phone = 3,
notebook,
desktop
}
下面咱们默认给 phone
赋值一个3
,那么上面两个值也会默认递增,会变成notebook = 4
、desktop = 5
。
注意事项 – 枚举对象递增
- 枚举对象成员递增值为 1
- 枚举对象成员递增只会看以后值的前一个枚举成员是否有值,有值的话前面顺次跟着递增。跟第一个枚举成员值无关
数字枚举对象会存在反向映射
enum device {
phone
notebook,
desktop
}
通过下面栗子咱们能够晓得,device.notebook = 1
。但还能够通过 device[1]
获取进去 notebook
,这就是因为存在 反向映射
(key 和 value 能够相互拜访)。
须要留神的是,只有数字枚举成员才会有反向映射,字符串或其它值是没有的。
来看下枚举对象被编译后的
<img src=”https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fd33df8cc99f4517907ffa807af4f973~tplv-k3u1fbpfcp-watermark.image” width=”100%”/>
咱们再来看一个问题
enum device {
phone = 2,
notebook = 1,
desktop
}
console.log(device.phone) // 2
console.log(device[2]) // desktop
能够看到下面代码中,device.phone = 2
,而后咱们应用反向这种形式拜访 device[2]
却是 desktop
。这是因为默认咱们给phone
赋值为 2
,而后又给notebook
赋值为 1
,这时desktop
跟着上一个枚举成员(notebook)值去递增,所以这时 2
曾经被替换为 desktop
了。
这里须要留神,防止踩坑,ts 是不会查看进去的反复的值。
字符串枚举
看过了下面的数字枚举,再来看字符串枚举,显然就明确字符串枚举成员的值必定都是 string
类型。字符串枚举对象是没有反向映射的。
enum device {
phone = "1",
notebook = "2",
desktop = "3"
}
咱们来看一下编译后的代码
<img src=”https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bc0e79c440bf4efc99c404019ea3abed~tplv-k3u1fbpfcp-watermark.image” width=”100%”/>
能够看到下面编译后的代码没有反向映射的代码。
字符串枚举是没有递增的,以后的枚举成员前一个值为字符串,那么以后的枚举对象如果不赋值就会报错。
enum device {
phone = "1",
notebook
}
下面这种状况就会导致编译阶段报错。” 枚举成员必须具备初始化表达式 ”,待会咱们就会讲到枚举对象的 表达式
。
异构枚举
异构枚举是啥呢,直白的说就是一个枚举对象中能够包含 数字枚举成员
和字符串枚举成员
,就是能够混合应用。然而咱们要正儿八经的应用枚举对象的话,个别还真不会应用异构枚举,就像文档说的一样,仿佛你并不会这么做。
enum Person {
name = "前端娱乐圈",
age = 18
}
在看一个栗子
enum Person {
name = "前端娱乐圈",
age = 3 * 6
}
下面这种是会报错的,“含字符串值成员的枚举中不容许应用计算值”,枚举对象成员有字符串的则不能再设置其它枚举对象成员为 计算的值 (3 * 6)
。然而能够间接写字面量的。上面咱们会讲到 计算
计算的和常量成员
枚举对象中的枚举成员都带有一个值,这个值是 计算的
或常量
。那么怎么看是计算的还是常量呢。这就讲到咱们下面说的 枚举对象成员表达式
,只有是表达式那肯定就是 常量
否则就是 计算的
。所以只须要晓得枚举成员是表达式就晓得它就是常量。
当满足上面其中一个条件那么它就是一个表达式。以下借用官网的规定条件
- 一个枚举表达式字面量(次要是字符串字面量或数字字面量)
- 一个对之前定义的常量枚举成员的援用(能够是在不同的枚举类型中定义的)
- 带括号的常量枚举表达式
- 一元运算符
+
,-
,~
其中之一利用在了常量枚举表达式 - 常量枚举表达式做为二元运算符
+
,-
,*
,/
,%
,<<
,>>
,>>>
,&
,|
,^
的操作对象。若常数枚举表达式求值后为NaN
或Infinity
,则会在编译阶段报错。
下面这些条件成立之后那么以后枚举成员就是一个常量。常量就是能够在编译阶段求值的
常量
enum obj {
index, // 满足条件 常量
index1 = index, // 满足条件 常量
age = 2 << 1, // 满足条件 常量
num = 30 | 2, // 满足条件 常量
num1 = 10 + 29 // 满足条件 常量
}
在看一下下面编译后的代码,能够看到间接在编译阶段求值了。
<img src=”https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/42beb700d9cd4d0a81d756d12384910b~tplv-k3u1fbpfcp-watermark.image” width=”100%”/>
计算的
enum obj {
nameLen = "前端娱乐圈".length, // 计算的
num = Math.random() * 100 // 计算的}
在看一下计算的编译后的代码是没有求值的。
<img src=”https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b517b83eba894ce88c1973b77478f37f~tplv-k3u1fbpfcp-watermark.image” width=”100%”/>
const 枚举
个别状况下,一般枚举对象就能够满足我的需要,然而有些状况比方为了节俭额定的开销和性能,咱们能够抉择应用常量枚举,常量枚举应用 const
关键字定义,它与一般枚举不同的时,它会在编译阶段删除该对象,且不能拜访该枚举对象,只能拜访该枚举对象成员。常量枚举的成员只能是常量枚举表达式,不能够应用计算值
const enum obj {
A = 1,
B = 3 * 6,
C = 1 & 2
}
console.log(obj) // 报错
须要留神下面这个常量枚举对象编译后的对象也是 ” 空 ” 的,零碎主动删除
const enum obj {
A = 1,
B = 3 * 6,
C = 1 & 2
}
console.log(obj.A) // 1
console.log(obj.B) // 8
console.log(obj.C) // 0
那么下面这个栗子,编译后只能看见 console.log
这些值。
<img src=”https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c34317c5a0c54d8a8ac34f9823c16a21~tplv-k3u1fbpfcp-watermark.image” width=”100%”/>
内部枚举
内部枚举应用 declare
关键字定义,文档形容:内部枚举用来形容曾经存在的枚举类型的形态,意思就是说内部枚举用来形容以后环境中存在的枚举对象。内部枚举和一般枚举的一个区别就是,在内部枚举外面没有初始化的枚举成员会当成一个 计算值
,而在一般枚举外面则是一个 常量
。
declare enum Enum {
A = 1,
B,
C = 2
}
console.log(Enum);
console.log(Enum.A)
下面这种执行完,你会发现不论执行枚举自身还是枚举成员都是报错,”Enum is not defined”。因为内部枚举编译后压根就没有生成。所以有明确内部枚举用处的小伙伴给解答一下,谢谢啦~
枚举成员的类型
枚举成员也能够被当做一个类型,就是能够指定某些变量的值必须是枚举成员的值。
枚举成员成为类型必须满足其中之一条件
- 字面量枚举成员是指不带有初始值的常量枚举成员
- 任何字符串字面量(如:
A
、B
) - 任何数字字面量(如:
1
,100
) - 利用了一元
-
符号的数字字面量(如:-1
,-100
)
enum obj {
name = "前端娱乐圈",
num = -100
}
interface msg {
title: obj.name;
num: obj.num
}
let json: msg = {
title: obj.name,
num: obj.num
}
感激
谢谢浏览,如有帮忙请点个关注、珍藏吧
感觉有帮忙能够关注 前端娱乐圈 公众号,每天为你推送一篇小常识
大家也能够加我 微信 交个敌人,能够找我聊天或拉你进技术交换群