What is the syntax to define enums in javascript?


Enums or Enumerated types are special data types that set variables as a set of predefined constants. In other languages enumerated data types are provided to use in this application. Javascript does not have enum types directly in it, but we can implement similar types like enums through javascript. In this article, we shall cover the syntaxes and uses to define enumerated types in javascript.

Below the syntax is given to show a basic implementation of enums in javascript, we can define an object to encapsulate the enumerated type, and assign keys for each enum value.

Syntax

const EnumType = {
   <enumConstant1> : <value1>,
   <enumConstant2> : <value2>,
   ...
   <enumConstantN> : <valueN>
}

Let us see one example, where we are using enum types with integer values in our javascript code.

Example

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 1, W: 2, N: 3, S: 4, NE: 31, NW: 32, SE: 41, SW: 42, } let myDirection = 41 if (myDirection === Direction.SE) { content += "Yes, your direction is South-East" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

This method can be applied for small codebases, but it may create some ambiguity in a few cases. For instance, in the following example, the developer may write the direction like the first letter in lowercase, but the string matching fails and returns false.

Example

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 'East', W: 'West', N: 'North', S: 'South', NE: 'North-East', NW: 'North-West', SE: 'South-East', SW: 'South-West', } let myDirection = 'south-East' if (myDirection === Direction.SE) { content += "Yes, your direction is South-East" + '<br>' } else { content += "No, your direction is not South-East" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Developers can also create unrelated enums, which got matched unintentionally, and as they are just two primitive type values, they got matched by conditional operators. Let us see this problem by an example −

Example

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: 1, W: 2, N: 3, S: 4, NE: 31, NW: 32, SE: 41, SW: 42, } const Vehicle = { Bus: 1, Car: 2, Motorcycle: 3, Truck: 4 } if (Direction.S === Vehicle.Truck) { content += "Yes, your vehicle type is truck" + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

In this example, two different enum types are created, but they got mixed while checking their values inside the if block. This is not desirable. Another thing is that using integers or numbers is semantically incorrect. For example, Directions are not integers or strings and they must have their types for better representation.

Enums with Symbol types

In Javascript, there is a concept called Symbol(). Symbols do not collide with one another. So if we define values by using Symbols it will be more appropriate and less error-prone. The syntax is given below.

Syntax

const EnumType = {
   const EnumType = {
      <enumConstant1> : Symbol(<value1>),
      <enumConstant2> : Symbol(<value2>),
      ...
      <enumConstantN> : Symbol(<valueN>)
   }

Let us see a similar example where Symbols are used, and let us check whether they are colliding or not.

Example

<html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: Symbol(1), W: Symbol(2), N: Symbol(3), S: Symbol(4), NE: Symbol(31), NW: Symbol(32), SE: Symbol(41), SW: Symbol(42), } const Vehicle = { Bus: Symbol(1), Car: Symbol(2), Motorcycle: Symbol(3), Truck: Symbol(4), } if (Direction.S === Vehicle.Truck) { content += "Yes, your vehicle type is truck" + '<br>' } else { content += "Checking two dissimilar types." + '<br>' } } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Creating Immutable Enum types

So far, we have seen few implementations of Enums. But there are some problems. In the last strategy also, we can update the value for an enum type just by assigning a new value to it. To restrict enum updating, we can make it immutable by passing the object inside the Object.freeze() method. Let us see this as an example.

Syntax

const EnumType = Object.freeze({
   <enumConstant1> : Symbol(<value1>),
   <enumConstant2> : Symbol(<value2>),
   ...
   <enumConstantN> : Symbol(<valueN>)
})

Example

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { const Direction = { E: Symbol(1), W: Symbol(2), N: Symbol(3), S: Symbol(4), NE: Symbol(31), NW: Symbol(32), SE: Symbol(41), SW: Symbol(42), } content += "Value of SW: " + JSON.stringify(Direction.SE.toString()) + '<br>' Direction.SE = Symbol(50); // updating with a new value content += "Value of SW: " + JSON.stringify(Direction.SE.toString()) + '<br>' // creating an immutable object type const Vehicle = Object.freeze({ Bus: Symbol(1), Car: Symbol(2), Motorcycle: Symbol(3), Truck: Symbol(4), }) content += "Value of Car: " + JSON.stringify(Vehicle.Car.toString()) + '<br>' Vehicle.Car = Symbol(10); // updating will not affect the old value content += "Value of Car: " + JSON.stringify(Vehicle.Car.toString()) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Enums with Classes

The final approach to defining an Enum type by using class Inside the class we are creating static members of different categories and assigning objects of the same class with different values passing through the constructor. So when we use them from outside, they can easily be used by using the class name and member (enum type) name. Let us see an example of this idea.

Example

<!DOCTYPE html> <html> <head> <title>HTML Console</title> </head> <body> <h3> Output Console </h3> <p> Output: </p> <div id="output"> </div> <div id="opError" style="color : #ff0000"> </div> <script> var content = '' var error = '' var opDiv = document.querySelector('#output') var opErrDiv = document.querySelector('#opError') // actual javascript code try { class Vehicles { static Car = new Vehicles('car'); static Bus = new Vehicles('bus'); static Truck = new Vehicles('truck'); static Motorcycle = new Vehicles('motorcycle'); constructor(name) { this.name = name; } } let mot = Vehicles.Motorcycle; // mot is a vehicle of type motorcycle content += "Is mot a Vehicle enum? " + JSON.stringify(mot instanceof Vehicles) + '<br>' content += "Is 'motorcycle' string itself a Vehicle enum? " + JSON.stringify(Symbol('motorcycle') instanceof Vehicles) + '<br>' console.log('Type of mot: ', mot.constructor.name) content += 'Type of mot: ' + JSON.stringify(mot.constructor.name) + '<br>' } catch (err) { error += err } finally { // display on output console opDiv.innerHTML = content opErrDiv.innerHTML = error } </script> </body> </html>

Conclusion

The enumerated or enum datatypes are used to create an ordered set of constants that can be used in our program to increase its readability. Unlike other languages, javascript has no native support for enumerated types. There are many different ways by which we can design enums in our javascript code. The basic enums can be generated by objects using integers or string-type values but this method is not suitable for many such cases, for instance, two enums with the same types may collide. The possible solution can be using Symbols to avoid the collision. We can also make our enums immutable to avoid unnecessary updates and the most appropriate method is by using classes as enum types.

Updated on: 23-Aug-2022

14K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements