In some programming languages, an enumeration (enum) is a set of named constants. This is consistent with the definition of the English word: the act of naming things one by one in a list; a list of this sort. Rather than relying on magic values in our code, we can use an enum to define a set of allowed values. This makes our code more predictable and less error-prone. JavaScript doesn’t support enums, but we can emulate them to an extent.

In TypeScript

Before we get started, here’s an example of enums in TypeScript. We can assume that the value of the drinkSize variable is computed somewhere; the declare statement is just to appease the compiler for this quick demonstration. The point is that because TypeScript is type-safe, we can rest assured that the value of the drinkSize variable is of type Size.

This means that instead of relying on magic strings in the switch statement, we can use the strict set of values defined by the enum. We know that the value of the drinkSize variable must be of type Size, so we don’t need to worry about a default case.

enum Size {
SMALL = "SMALL",
MEDIUM = "MEDIUM",
LARGE = "LARGE",
}

// Tells TypeScript there is a variable called `drinkSize` of type `Size`
// and to not worry about where it came from.
declare var drinkSize: Size;

switch (drinkSize) {
case Size.SMALL:
var price = 3.35;
break;
case Size.MEDIUM:
var price = 3.7;
break;
case Size.LARGE:
var price = 3.9;
break;
}

The Object.freeze() method

Last week, I covered the static Object.freeze() method. This method is the perfect candidate for enumeration emulation (I enjoyed the rhyming and alliteration there, sorry) in JavaScript. I first saw this technique in Steve Griffith’s video, Improving Your JavaScript with Enums.

As before, instead of relying on magic strings, we can use the set of values defined by the “enum.” The only downside is that because JavaScript isn’t type-safe, we can’t enforce that the drinkSize variable is restricted to this set of values. I still think this is a useful technique, however.

const Size = Object.freeze({
SMALL: "SMALL",
MEDIUM: "MEDIUM",
LARGE: "LARGE",
});

// Assume `drinkSize` is declared somewhere.
switch (drinkSize) {
case Size.SMALL:
var price = 3.35;
break;
case Size.MEDIUM:
var price = 3.7;
break;
case Size.LARGE:
var price = 3.9;
break;
}

Null prototype

The Object.freeze() technique is nice, but I would also make sure the object has a null prototype. This may not look pretty, but it ensures that the object doesn’t inherit from Object.prototype. In my opinion, this makes it more like a true enum.

const Size = Object.freeze({
SMALL: "SMALL",
MEDIUM: "MEDIUM",
LARGE: "LARGE",
__proto__: null,
});

Summary

An enumeration (enum) is a set of named constants that helps us avoid magic values in our code. Although JavaScript doesn’t support enums, it’s possible to emulate them using a constant assigned to a frozen object with a null prototype. Because JavaScript isn’t type-safe, we can’t enforce that a variable is restricted to this set of values, but I think this is a useful technique nonetheless.