Я хотел бы определить структуру с перечислением в JS, но имеет два требования:
- Значения могут быть доступны только для чтения, т.е. пользователи не могут их назначать.
- Значения (0, 1, 2,...) могут быть отображены обратно в имена (как в Java метод имени)
Методы, которые я знаю для создания перечислений, подобных этому, обычно соответствуют одному требованию или другому, а не тем и другим.
Я пробовал:
const MyEnum = {
a: 0,
b: 1,
c: 2
};
Само перечисление является постоянным, но значения все еще изменяемы, и я не могу эффективно преобразовать значения обратно в имена.
При записи enum
в Typescript он выводит:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["a"] = 0] = "a";
MyEnum[MyEnum["b"] = 1] = "b";
MyEnum[MyEnum["c"] = 2] = "c";
})(MyEnum || (MyEnum = {}));
Это может отображаться в обоих направлениях, но по-прежнему не имеет постоянных значений.
Единственный вариант, который я нашел, который отвечает обоим требованиям, будет использовать getters в классе:
class MyEnum {
get a() {
return 0;
}
...
}
Этот метод значительно ограничивает юридические имена и имеет много накладных расходов, особенно в браузерах, которые не имеют встроенных геттеров (или не могут).
@Shmiddty предложил заморозить объект:
const MyEnum = Object.freeze({
a: 0,
b: 1,
c: 2
});
Это удовлетворяет постоянным требованиям, но не обеспечивает отличный способ сопоставления значений с именами.
Я мог бы написать помощник, который строит обратное отображение, например:
function reverseEnum(enum) {
Object.keys(enum).forEach(k => {
enum[enum[k]] = k;
});
}
Но любое программное решение для создания обратного сопоставления будет сталкиваться с проблемами, если исходный объект заморожен или фактически фактически постоянным.
Есть ли в JS чистое, сжатое решение?