使用枚举我们可以定义一些有名字的数字常量,一个枚举类型中可以包含一个至多个成员,并且枚举成员是只读,不能修改的。当变量的值,只能是几个固定值中的一个,我们就可以使用枚举来实现
数字枚举
- 声明枚举类型
enum Gender { Female, Male }
- 使用枚举
// 创建变量,并赋类型为枚举
let userGender: Gender
// 访问枚举的成员
userGender = Gender.Female
- 注意:这里所说的数字枚举并非是枚举成员是数字,而是说枚举成员的值是数字,上面的例子就相当于是
enum Gender {
Female = 0,
Male = 1
}
我们可以在控制台打印出枚举的值
console.log(Gender.Female); // 0
- 数字枚举的默认值,值自增行为
通过上面的例子,你应该会发现,如果我们没有给枚举成员赋初始值,枚举类型会自动给成员赋值,按照先后从0开始,有点像数组的index
那我们可不可以手动赋值?可以!!
不按照枚举的默认顺序为成员赋值
enum numbox {
one=1,
four=6
}
let n = numbox.one
let m = numbox.four
console.log(n);
console.log(m);
看看这终端打印的结果
Snipaste_2021-04-14_17-01-14.png
结果说明,我们给成员赋的初始值是啥,那么这个成员的值就是啥,那如果给一个成员赋值,另一个成员不赋值,没有赋值的成员的值是多少?
enum numbox {
one=1,
four=6,
six,
ten
}
let n = numbox.six
let m = numbox.ten
console.log(n);
console.log(m);
看结果
Snipaste_2021-04-14_17-06-32.png
从此可以看出,未被赋值的元素,它的元素值就是前面已赋值的元素值加一,而不是他所在的位置,这和数组的index就不一样了
- 运算
支持一元运算符与二元运算符,但运算结果为NaN或者Infinity无穷时,编译时会报错的
字符串枚举
顾名思义就是给枚举成员赋上一个字符串类型的值
enum stringBox {
one="一",
two="二",
there
="三"
}
Snipaste_2021-04-14_17-19-55.png
- 无值自增行为
对于字符串枚举,每一个成员必须赋上字符串类型的值,否则编译不通过
异构枚举
就是数字枚举和字符串枚举混用啦
enum Enum {
A = 0,
B = 'hello'
}
常数枚举
当访问枚举值时,为了避免生成多余的代码和间接引用,可以使用常数枚举,常数枚举就是通过const 来修饰 enum关键字
const enum numberBox {
one,
two,
there,
four
}
let n = numberBox.one
console.log(n);
将上面的程序编译成js程序后变成了
var n = 0 /* one */;
console.log(n);
编译出的文件中就没有枚举的定义了,常数枚举只能使用常数枚举表达式并且不同于常规的枚举的是它们在编译阶段会被删除。 常数枚举成员在使用的地方被内联进来。 这是因为常数枚举不可能有计算成员。
枚举的反向映射
枚举是在运行时真正存在的一个对象。 其中一个原因是因为这样可以从枚举值到枚举名进行反向映射。将下面程序编译成js文件
enum numberBox {
one,
two,
there,
four
}
js文件
var numberBox;
(function (numberBox) {
numberBox[numberBox["one"] = 0] = "one";
numberBox[numberBox["two"] = 1] = "two";
numberBox[numberBox["there"] = 2] = "there";
numberBox[numberBox["four"] = 3] = "four";
})(numberBox || (numberBox = {}));
生成的代码中,枚举类型被编译成一个对象,它包含双向映射(name -> value)和(value -> name)。
双向映射
let n = numberBox.one
console.log(n);
let N = numberBox[n]
console.log(N);
Snipaste_2021-04-14_17-38-01.png
注:字符串枚举,外部枚举不会生成反向映射
外部枚举
外部枚举使用declare 修饰eunm关键字,用来描述已经存在的枚举类型的形状。
declare enum Enum {
A = 1,
B,
C = 2
}
外部枚举和非外部枚举之间有一个重要的区别,在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的。
关于外部枚举,大家可以参考这篇文章https://www.jianshu.com/p/3a040670aa65
网友评论