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.
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.