当前位置:网站首页>LayaBox---TypeScript---枚举
LayaBox---TypeScript---枚举
2022-07-30 17:38:00 【格拉格拉】
目录
使用枚举我们可以定义一些带名字的常量。
使用枚举可以清晰地表达意图或创建一组有区别的用例。
TypeScript支持数字的和基于字符串的枚举。
1.数字枚举:
默认起始值为0, 也可手动指定,如下例指定起始值为1
enum Direction {
Up = 1,
Down,
Left,
Right
}使用枚举:通过枚举的属性来访问枚举成员,和枚举的名字来访问枚举类型:
enum Response {
No = 0,
Yes = 1,
}
function respond(recipient: string, message: Response): void {
// ...
}
respond("Princess Caroline", Response.Yes)简短地说,不带初始化器的枚举或者被放在第一的位置,或者被放在使用了数字常量或其它常量初始化了的枚举后面。
换句话说,下面的情况是不被允许的:
enum E {
A = getSomeValue(),
B, // error! 'A' is not constant-initialized, so 'B' needs an initializer
}2.字符串枚举
在一个字符串枚举里,每个成员都必须用字符串字面量,或另外一个字符串枚举成员进行初始化。
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}由于字符串枚举没有自增长的行为,字符串枚举可以很好的序列化。
3.异构枚举
从技术的角度来说,枚举可以混合字符串和数字成员。
除非你真的想要利用JavaScript运行时的行为,否则不建议这么做。
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}4.计算的和常量成员
每个枚举成员都带有一个值,它可以是 常量或 计算出来的。
当满足如下条件时,枚举成员被当作是常量:
它是枚举的第一个成员且没有初始化器,这种情况下它被赋予值 0:
enum E { X }
//----------------------------------------------------
它不带有初始化器且它之前的枚举成员是一个 数字常量。 这种情况下,
当前枚举成员的值为它上一个枚举成员的值加1。
// All enum members in 'E1' and 'E2' are constant.
enum E1 { X, Y, Z }
enum E2 {
A = 1, B, C
}枚举成员使用 常量枚举表达式初始化。 常数枚举表达式是TypeScript表达式的子集,它可以在编译阶段求值。 当一个表达式满足下面条件之一时,它就是一个常量枚举表达式:
1.一个枚举表达式字面量(主要是字符串字面量或数字字面量)- 2.一个对之前定义的常量枚举成员的引用(可以是在不同的枚举类型中定义的)
- 3.带括号的常量枚举表达式
- 4.一元运算符
+,-,~其中之一应用在了常量枚举表达式 - 5.常量枚举表达式做为二元运算符
+,-,*,/,%,<<,>>,>>>,&,|,^的操作对象。 若常数枚举表达式求值后为NaN或Infinity,则会在编译阶段报错。
所有其它情况的枚举成员被当作是需要计算得出的值。
enum FileAccess {
// constant members
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// computed member
G = "123".length
}5.联合枚举与枚举成员的类型
存在一种特殊的非计算的常量枚举成员的子集:字面量枚举成员。
字面量枚举成员是指不带有初始值的常量枚举成员,或者是值被初始化为
- 任何字符串字面量(例如:
"foo","bar","baz") - 任何数字字面量(例如:
1,100) - 应用了一元
-符号的数字字面量(例如:-1,-100)
当所有枚举成员都拥有字面量枚举值时,它就带有了一种特殊的语义。
1,枚举成员成为了类型! 例如,我们可以说某些成员 只能是枚举成员的值:
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square,
// ~~~~~~~~~~~~~~~~ Error!
radius: 100,
}
//----------------------------------------------------------------
2.是枚举类型本身变成了每个枚举成员的 联合。
enum E {
Foo,
Bar,
}
function f(x: E) {
if (x !== E.Foo || x !== E.Bar) {
// ~~~~~~~~~~~
// Error! Operator '!==' cannot be applied to types 'E.Foo' and 'E.Bar'.
}
}这个例子里,我们先检查 x是否不是 E.Foo。 如果通过了这个检查,然后 ||会发生短路效果, if语句体里的内容会被执行。 然而,这个检查没有通过,那么 x则 只能为 E.Foo,因此没理由再去检查它是否为 E.Bar。
6.运行时的枚举
枚举是在运行时真正存在的对象。 例如下面的枚举:
enum E {
X, Y, Z
}
function f(obj: { X: number }) {
return obj.X;
}
// Works, since 'E' has a property named 'X' which is a number.
f(E);7.反向映射
除了创建一个以属性名做为对象成员的对象之外,数字枚举成员还具有了 反向映射,从枚举值到枚举名字。
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
//TypeScript可能会将这段代码编译为下面的JavaScript:
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"生成的代码中,枚举类型被编译成一个对象,它包含了正向映射( name -> value)和反向映射( value -> name)。 引用枚举成员总会生成为对属性访问并且永远也不会内联代码。
️注意: 不会为字符串枚举成员生成反向映射。
8.const 枚举
为了避免在额外生成的代码上的开销和额外的非直接的对枚举成员的访问,我们可以使用 const枚举。
const enum Enum {
A = 1,
B = A * 2
}常量枚举只能使用常量枚举表达式,并且不同于常规的枚举,它们在编译阶段会被删除。 常量枚举成员在使用的地方会被内联进来。 之所以可以这么做是因为,常量枚举不允许包含计算成员。
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]
生成后的代码为:
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];9.外部枚举
外部枚举(declare)用来描述已经存在的枚举类型的形状。
declare enum Enum {
A = 1,
B,
C = 2
}外部枚举和非外部枚举之间有一个重要的区别:
正常的枚举: 没有初始化方法的成员被当成常数成员。
非常数的外部枚举: 没有初始化方法时被当做需要经过计算的。
边栏推荐
- 查询表中开始日期与结束日期
- Informatics Olympiad 1915: [01NOIP Popularization Group] Greatest Common Divisor and Least Common Multiple | Luogu P1029 [NOIP2001 Popularization Group] The problem of the greatest common divisor and
- C陷阱与缺陷 第6章 预处理器 6.2 宏并不是函数
- shell快速移植
- C陷阱与缺陷 第7章 可移植性缺陷 7.2 标识符名称的限制
- matlab simulink锂离子电池智能充电策略研究
- Mathematical Principles of Graph Convolutional Neural Networks——A Preliminary Study on Spectral Graph Theory and Fourier Transform
- 【云商店公告】关于7月30日帮助中心更新通知
- LeetCode318: Maximum product of word lengths
- 分账系统二清解决方案如何助力电商平台合规经营?
猜你喜欢
随机推荐
PyTorch 猫狗分类源代码及数据集
主流的深度学习推理架构有哪些呢?
JMeter笔记3 | JMeter安装和环境说明
升级 MDK 5.37 后的问题处理: AC6编译选项, printf, 重启失效等
Error occurred while trying to proxy request项目突然起不来了
【云商店公告】关于7月30日帮助中心更新通知
关于内和调试无法查看ntdll内存的问题
LeetCode 952. 按公因数计算最大组件大小
MySQL中的存储过程(详细篇)
Error EPERM operation not permitted, mkdir 'Dsoftwarenodejsnode_cache_cacach Two solutions
C语言向MySQL插入数据
Ecplise执行C语言报错:cannot open output file xxx.exe: Permission denied
Error EPERM operation not permitted, mkdir ‘Dsoftwarenodejsnode_cache_cacach两种解决办法
Insert data into MySQL in C language
测试行业干了5年,从只会点点点到了现在的测试开发,总算是证明了自己
fast shell porting
Redis缓存穿透-热点缓存并发重建-缓存与数据库双写不一致-缓存雪崩
【AAAI2020】阿里DMR:融合Matching思想的深度排序模型
链表Oj练习题 纯C语言
Basic knowledge points in js - BOM









