I’m rebuilding an old Java project in Javascript, and realized that there’s no good way to do enums in JS.
The best I can come up with is:
const Colors = { RED: Symbol("red"), BLUE: Symbol("blue"), GREEN: Symbol("green") }; Object.freeze(Colors);
The const
keeps Colors
from being reassigned, and freezing it prevents mutating the keys and values. I’m using Symbols so that Colors.RED
is not equal to 0
, or anything else besides itself.
Is there a problem with this formulation? Is there a better way?
(I know this question is a bit of a repeat, but all the previous Q/As are quite old, and ES6 gives us some new capabilities.)
EDIT:
Another solution, which deals with the serialization problem, but I believe still has realm issues:
const enumValue = (name) => Object.freeze({toString: () => name}); const Colors = Object.freeze({ RED: enumValue("Colors.RED"), BLUE: enumValue("Colors.BLUE"), GREEN: enumValue("Colors.GREEN") });
By using object references as the values, you get the same collision-avoidance as Symbols.
Advertisement
Answer
Is there a problem with this formulation?
I don’t see any.
Is there a better way?
I’d collapse the two statements into one:
const Colors = Object.freeze({ RED: Symbol("red"), BLUE: Symbol("blue"), GREEN: Symbol("green") });
If you don’t like the boilerplate, like the repeated Symbol
calls, you can of course also write a helper function makeEnum
that creates the same thing from a list of names.