Explain Codes LogoExplain Codes Logo

How can I guarantee that my enums definition doesn't change in JavaScript?

javascript
enum
javascript-best-practices
object-freeze
Alex KataevbyAlex Kataev·Sep 30, 2024
TLDR

Rigorously lock down your enums in JavaScript by employing Object.freeze() on an object, rendering it immutable:

const STATUS = Object.freeze({ NOT_STARTED: 0, IN_PROGRESS: 1, FINISHED: 2 });

Trying to tamper with STATUS will prove futile and your enums remain unchanged as well as trustworthy.

Const enums: Keep those pesky reassignments at bay

Utilize const when defining enums. This stalwartly prevents your enums from any reassignment escapades:

const COLORS = { RED: '#FF0000', GREEN: '#00FF00', BLUE: '#0000FF' }; Object.freeze(COLORS);

Enumerate a little rebelliously with string values. Improves readability and eases debugging:

const ROLES = { ADMIN: 'Administrator', GUEST: 'Guest', MEMBER: 'Member' }; Object.freeze(ROLES); // ♫ Let it go, Let it go! Can't reassign anymore! ♫

Giving enums the TypeScript/Flow treatment

Object.freeze() is a knight in shining armor for JavaScript enums. But consider leveling up with TypeScript or Flow to truly lock the box of type safety:

enum Status { NotStarted, InProgress, Finished }

Eccentrically designed, TypeScript preserves immutability in enums by default and dismisses your inadvertent modifications.

Shields up! Guarding nested objects

Working with nested objects or enums? Brace for deep freezing objects. Turn to ally libraries like deep-freeze to recursively apply immutability:

const deepFreeze = require('deep-freeze'); const COMPLEX_STATUS = deepFreeze({ NOT_STARTED: { code: 0, desc: 'Not started' }, IN_PROGRESS: { code: 1, desc: 'In progress' }, FINISHED: { code: 2, desc: 'Finished' } }); // Not just a cool Marvel movie, mind you...

Unveiling a deeper truth: JavaScript's Object.freeze() takes care of top-level objects, and deepFreeze takes it a notch deeper.

Symbol overloading: Tackling value uniqueness

With enum values at war, wave the flag of Symbol() to ensure uniqueness and nullify those pesky collisions:

const LEVELS = { LOW: Symbol('low'), MEDIUM: Symbol('medium'), HIGH: Symbol('high') }; Object.freeze(LEVELS); // More freezed than a popsicle in Siberia!

Unique, immutable and not candy crush level-based! Symbols are the to-go for enums presenting unique constants.

Strategic selection of implementation

Choosy programmers choose wisely! Your enum implementation will depend on your project's unique needs. Take a look at Object.freeze(), TypeScript, or other handy libraries to find the right balance of safety and usability.