javascriptenumsecmascript-6immutabilitysymbols

Enums in Javascript with ES6


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.


Solution

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