Let’s start with a question: Can numbers refer not to the amount but types of something?
The short answer is they can. A number can mean anything that we want, starting from types of cars (say, 1 is for truck) or even the status of a calculation (for instance, 1 is for started).
We might think that just having a variable is enough to understand it. Let’s have a quick look at the code below:
Wow! We can figure out the type of car! But what if we need to add more car types?
We can do this infinitely, and it will still work. These types won’t, however, be logically connected. They’ll be just separate constants that can be moved anywhere in your code. Handling variables this way is a little bit messy.
With that as our background, let me introduce Enums (the enumeration type). With Enums, a developer can define a set of named constants. This makes it easier to document or create a set of distinct cases.
Using Enums might also mitigate spelling errors, as Enums are unchangeable. And it can make your code safer and cleaner (that is, searchable by name, with the ability to remove the magic values, and so on). Think of Enums as a kind of closed class, the instances of which are predefined statically.
As we mentioned before, Enums are name constants or, in other words, key-value pairs, so we can simply create an object.
The naming convention here is a matter of taste. The most widespread one is PascalCase for name, and UPPER_CASE for keys. But again, it’s up to you to decide how you want it to look.
Note that this still won’t replicate real Enums, because the values can be changed easily.
In native JS, it’s possible to keep properties of the object unchanged. The first option is to use the defineProperty method, but in ES6 we’ve got the freeze method for doing so:
That’s it for basic scenarios. For more complex scenarios, where values should be objects or another logic should be included, we can develop our own Enum implementation.
As we know, Enum is a class with predefined instances. So, let’s have a look at our implementation closely. We’ll use ES6, since older versions are not really relevant here:
In this case, we’re literally predefining the instances of the class that can be used in our business logic, and adding the toString method as an example of a custom logic for our enumeration.
We can make this example iterable, add more useful methods, and use the Proxy class for restricting the direct change of the properties, but I’ll leave that for your self-study since it goes beyond the scope of this article.
You can also use npm packages like enumify, which help implement the enum pattern itself, or an enum package that provides complete implementation with more features, like namespaces.
Finally, if you use TypeScript in your project, Enums are available right out of the box.