枚举
普通枚举
枚举和对象的重要差异在于,对象是单向映射的,我们只能从键映射到键值。而枚举是双向映射的,即你可以从枚举成员映射到枚举值,也可以从枚举值映射到枚举成员。
enum Items {
Foo,
Bar,
Baz
}
const fooValue = Items.Foo; // 0
const fooKey = Items[0]; // "Foo"
这一现象产生的原因与 enum
的编译产物有关,如以上的枚举会被编译为以下 JavaScript 代码。
'use strict';
let Items;
(function (Items) {
Items[Items['Foo'] = 0] = 'Foo';
Items[Items['Bar'] = 1] = 'Bar';
Items[Items['Baz'] = 2] = 'Baz';
})(Items || (Items = {}));
obj[k] = v 的返回值即是 v,因此这里的 obj[obj[k] = v] = k
本质上就是进行了 obj[k] = v
与 obj[v] = k
这样两次赋值。
常量枚举
常量枚举和枚举相似,只是其声明多了一个 const
。
const enum Items {
Foo,
Bar,
Baz
}
const fooValue = Items.Foo; // 0
常量枚举和普通枚举的差异主要在可访问性与编译产物。对于常量枚举,你只能通过枚举成员访问枚举值(而不能通过值访问成员)。同时,在编译产物中并不会存在一个额外的辅助对象(如上面的 Items 对象),对枚举成员的访问会被直接内联替换为枚举的值。以上的代码会被编译为如下形式。
const fooValue = 0 /* Foo */; // 0