DEV Community

Cover image for Improving your JavaScript with Enums
Steve Griffith
Steve Griffith

Posted on

Improving your JavaScript with Enums

Enumerations (Enums) are a common data structure feature in many programming languages. While JavaScript does not natively have this feature, we can quickly and easily add them.

What is an Enum?

Before we jump into the code and learn how to create an Enum, we should discuss what one is. Let's start with an Array. This Array is a list of possible error types that we could have in our web app.

const errors = ['Data Error', 'Lunch Error', 'Mom Error'];
Enter fullscreen mode Exit fullscreen mode

While an Array allows us to store a list of error types that could be used later, it does require the developer to memorized the names and the order that they appear in the Array.

console.log( errors[0] );
//if you remember that zero refers to 'DataError'
//then you get the right value.
Enter fullscreen mode Exit fullscreen mode

An Enumeration solves this problem by creating an uneditable list of values where each value has a String name as the key.

So, this can be more closely replicated with a JavaScript Object.

const errors = {
  DATAERROR: 'Data Error',
  LUNCHERROR: 'Lunch Error',
  MOMERROR: 'Mom Error'
}
Enter fullscreen mode Exit fullscreen mode

With an Object we avoid this issue of having to remember the position of each value.

console.log( errors['DATAERROR'] );
Enter fullscreen mode Exit fullscreen mode

We still have the problem that any of the keys or values can be edited or removed.

So, an Enumeration is a list of key-value pairs that cannot be altered at runtime.

Creating JavaScript Enums

Accepting that an Object is a better choice than an Array for replicating an Enum, we need to solve the readonly issue. That brings us to the Object.freeze method.

The Object.freeze method that allows us take any object and change the configurable and writable property descriptors of every property so that no changes can be made to either the key or the value.

const errors = Object.freeze({
  DATAERROR: 'Data Error',
  LUNCHERROR: 'Lunch Error',
  MOMERROR: 'Mom Error'
});

console.log( errors['LUNCHERROR'] );
//we can use either square bracket syntax 
//or dot notation to access the values
console.log( errors.MOMERROR );
Enter fullscreen mode Exit fullscreen mode

The use of const will also prevent any new value being assigned to errors and replacing the original Object.

Applications of Enums

As an example for how we could use our Enum we can imagine a simple web app that attempts to do some asynchronous tasks, in sequence, and when it fails any of them, it will throw an error that is specific to the task.

Promise.resolve(123)
  .then(async (id)=>{
    let url = `https://example.com/users/${id}`;
    let resp = await fetch(url)
    if(!resp.ok) throw new Error(errors['DATAERROR']);
    return 'burger';
  })
  .then(async (food) => {
    let isGood = await enjoyAsyncLunch(food);
    if(!isGood) throw new Error(errors['LUNCHERROR']);
    return true;
  })
  .then((ready) => {
    if( !askMomForPermission() ) throw new Error(errors.MOMERROR);
  })
  .catch((err)=> {
    console.error(`Reason for failure is ${err.message}`);
  });
Enter fullscreen mode Exit fullscreen mode

A nice added benefit of creating our Enum Object is that now, most IDEs, like VSCode, will be able to use code-complete to show you the possible values for errors.

Top comments (15)

Collapse
 
incrementis profile image
Akin C.

Hi Steve Griffith,

thank you for your article.
I like how you switch from arrays to enums because I think it makes it easier to understand.
I'm not sure if that's intentional, but I also like the touch of humor found in your article.

Overall, I think the article is good enough to fit into an MDN documentation :D.

Collapse
 
prof3ssorst3v3 profile image
Steve Griffith

That was exactly my intent with the arrays.

Collapse
 
fadehelix profile image
Adam Dziendziel

Thanks for the hint with Object.freeze() when creating enum 💪

Collapse
 
yourmdsarfaraj profile image
MD Sarfaraj

A well-written explanation. Thank your for sharing !!

Collapse
 
lyavale95 profile image
LyAVALE95

Great article thanks

Collapse
 
elijahtrillionz profile image
Elijah Trillionz

Thanks for the article Griffith.

I needed enums for my library project, your article helped me figure it out. Thanks

Collapse
 
guido_dipilla_39b550ef6d7 profile image
Guido DiPilla

Thanks for sharing. Most concise and easily understandable explanation I’ve seen…

Collapse
 
decker67 profile image
decker

I would prefer Errortype.DATA_ERROR.

Collapse
 
prof3ssorst3v3 profile image
Steve Griffith

:) You can call them whatever you like.
I usually prefer the dot syntax too.
The valuable thing is having strings for names, instead of numbers, plus names and values that cannot be altered.

Collapse
 
decker67 profile image
decker

You can but you shouldn't, naming counts.

Thread Thread
 
prof3ssorst3v3 profile image
Steve Griffith

:D
Very true.

Collapse
 
martinszeltins profile image
Martins

Why not just use TypeScript which has built-in enums and many more goodies.

Collapse
 
prof3ssorst3v3 profile image
Steve Griffith

Because a lot more people use JavaScript, not Typescript when developing.
When Typescript compiles back into JS, this is what it is doing.

Collapse
 
majinxin8023 profile image
Mr.ma

Map 不香吗?

Collapse
 
prof3ssorst3v3 profile image
Steve Griffith

Maps have the same problem as objects - they can be altered. Object.freeze( ) gives the best version of an enum.