How can I define an enum in JavaScript?

Angelos Chalaris · JavaScript, Object, Class, Symbol, Generator · Jun 12, 2021

TypeScript's enums are a very convenient feature present in many other languages. JavaScript, however, does not have a similar concept at this time. But what JavaScript lacks in syntactic sugar it makes up for in terms of flexibility.

The easiest way to define an enum would be to use Object.freeze() in combination with a plain object. This will ensure that the enum object cannot be mutated.

const daysEnum = Object.freeze({
  monday: 0,
  tuesday: 1,
  wednesday: 2,
  thursday: 3,
  friday: 4,
  saturday: 5,
  sunday: 6
});

Taking this one step further, one could extract the logic into a function with a variable number of arguments and producing a frozen object. There is very little benefit to this technique, so a better alternative would be to create a simple class. After all, enums are more common in object-oriented programming languages, so this sounds like a great fit.

An Enum class would only require a constructor with a variable number of arguments. Its job is to add each key to the enum object and freeze the newly created instance. A potential enhancement would be to provide access to the enum values as strings. Obviously, this can be accomplished using Object.keys(), but a named method could result in a conflict with one of the enum's values, let alone the method polluting the result.

Using an ES6 symbol is the obvious solution here, as it will not pollute the result of Object.keys() and it will never conflict with any values in the enum. Taking this one step further, Symbol.iterator would be a great choice as it would allow for the enum to be considered iterable and make it even more useful. Putting all of this together, here's my Enum class and how to use it:

class Enum {
  constructor(...keys) {
    keys.forEach((key, i) => {
      this[key] = i;
    });
    Object.freeze(this);
  }

  *[Symbol.iterator]() {
    for (let key of Object.keys(this)) yield key;
  }
}

const daysEnum = new Enum(
  'monday',
  'tuesday',
  'wednesday',
  'thursday',
  'friday',
  'saturday',
  'sunday'
);

const days = [...daysEnum]; // Array of the enum values as strings

Recommended snippets & collections

  • JavaScript generator functions are a more advanced yet very powerful JavaScript ES6 feature, which you can start using in your code right now.

  • Function property names

    JavaScript, Object

    Gets an array of function property names from own (and optionally inherited) enumerable properties of an object.

  • Walk through object

    JavaScript, Object

    Creates a generator, that walks through all the keys of a given object.

  • Find first matching key

    JavaScript, Object

    Finds the first key that satisfies the provided testing function. Otherwise undefined is returned.