Cómo congelar un enum en JavaScript y no volverse loco

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: Por qué tu enum puede «tener fugas» y cómo evitarlo



Imagina que trabajas en un gran proyecto en JavaScript. Has creado un enum para los estados de un pedido: PENDING, SHIPPED, DELIVERED. Todo funciona perfectamente, hasta que en uno de los módulos algún desarrollador (o tú mismo seis meses después) escribe accidentalmente: OrderStatus.PENDING = 'CANCELLED'. O, peor aún, Object.assign(OrderStatus, { NEW_STATUS: 'hacked' }). ¡Boom! La lógica de la aplicación se rompe, el error llega a producción y pasas una noche sin dormir depurando.



Este es un problema clásico que ha acumulado miles de visitas en Stack Overflow. La pregunta «How can I guarantee that my enums definition doesn't change in JavaScript?» atormenta a muchos. Y con razón: JavaScript es un lenguaje dinámico y sus objetos son mutables por defecto. Pero hay una solución, y hoy analizaremos todas las formas de proteger de manera confiable tus enumeraciones.



En este artículo te mostraré varios enfoques probados: desde el simple Object.freeze() hasta técnicas avanzadas con Symbol y TypeScript. Aprenderás a escribir enums inmutables que resistirán cualquier cambio accidental (o no tan accidental).



El problema: por qué un enum en JavaScript es solo un objeto



A diferencia de algunos lenguajes (C#, Java, Rust), JavaScript no tiene una construcción nativa enum. Los desarrolladores los emulan usando objetos simples:



const OrderStatus = {  PENDING: 'pending',  SHIPPED: 'shipped',  DELIVERED: 'delivered'};


Esto funciona, pero esta emulación tiene un defecto fatal: cualquiera puede cambiar el valor. Y no solo es por mala intención, a menudo sucede accidentalmente:



  • Asignación accidental en un bucle o callback.
  • ¿Inmutabilidad? Te olvidaste y alguien extendió el objeto.
  • Librerías que pueden mutar los objetos que se les pasan.


El problema se agrava porque en bases de código grandes es difícil rastrear estos cambios. Por eso la pregunta sobre cómo proteger un enum de cambios es tan popular.



Solución n.º 1: Object.freeze() — tu primer escudo



La forma más simple y común es usar Object.freeze(). Este método hace que el objeto sea inmutable: no podrás agregar, eliminar ni modificar propiedades.



Cómo funciona



const OrderStatus = Object.freeze({  PENDING: 'pending',  SHIPPED: 'shipped',  DELIVERED: 'delivered'});

// Intentar cambiar — no funcionaráOrderStatus.PENDING = 'CANCELLED'; // Silencio (en modo estricto — error)OrderStatus.NEW = 'new'; // No se agregarádelete OrderStatus.SHIPPED; // No se eliminará

console.log(OrderStatus.PENDING); // 'pending' — el valor no ha cambiado


¿Por qué es útil? Object.freeze() funciona a nivel del propio objeto. Es un mecanismo incorporado que no requiere librerías adicionales. Es ideal para proteger un enum en JavaScript contra mutaciones accidentales.



Limitaciones de Object.freeze()



  • Congelación superficial — si los valores del enum son objetos, estos siguen siendo mutables.
  • No protege contra la reasignación — si usas let en lugar de const, la variable se puede sobrescribir por completo.
  • No genera errores en modo no estricto — los cambios simplemente se ignoran, lo que puede ocultar un error.


Pero para enums simples, esto es más que suficiente. Si necesitas protección adicional, sigue leyendo.



Solución n.º 2: Usa const + Object.freeze() para un bloqueo total



La combinación de const (protege contra la reasignación de la variable) y Object.freeze() (protege contra

Blogs

Book Recommendations