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.
Also check Enumify, a very good and well featured library for ES6 enums.
Hope this will help somebody.
Best regards,
Emmanuel
You could use ES6 Map
Check how TypeScript does it. Basically they do the following:
Use symbols, freeze object, whatever you want.
If you don't need pure ES6 and can use Typescript, it has a nice
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
As mentioned above, you could also write a
makeEnum()
helper function:Use it like this:
Whilst using
Symbol
as the enum value works fine for simple use cases, it can be handy to give properties to enums. This can be done by using anObject
as the enum value containing the properties.For example we can give each of the
Colors
a name and hex value:Including properties in the enum avoids having to write
switch
statements (and possibly forgetting new cases to the switch statements when an enum is extended). The example also shows the enum properties and types documented with the JSDoc enum annotation.Equality works as expected with
Colors.RED === Colors.RED
beingtrue
, andColors.RED === Colors.BLUE
beingfalse
.