---
title: "Por qué siempre uso enum en JavaScript"
description: "Por qué los valores con nombre y la búsqueda por símbolos son más seguros que los literales de cadena en JavaScript mantenible."
date: 2024-05-23
---

Escribí esta nota bajo la influencia de un artículo ya eliminado que
proponía usar objetos en lugar de `enum` en TypeScript.

<zoom-img src="/medium/img/2feb64992e54/image-01.png" alt="Comparación entre enum y un objeto de constantes" width="100%"></zoom-img>

En vez de:

``` ts
enum Colors {
  BLUE = 'blue', GREEN = 'green', RED = 'red',
}
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');
```

se sugería usar:

``` ts
const Colors = {
  BLUE: 'blue', GREEN: 'green', RED: 'red',
} as const;
type Colors = typeof Colors[keyof typeof Colors];
function printColor(color: Colors) { console.log(color); }
printColor(Colors.BLUE);
printColor('blue');
```

La ventaja sería poder escribir `'blue'` sin importar el módulo que
define la enumeración.

En mi artículo sobre la meta última de programar describo una jerarquía
de objetivos parecida a la pirámide de Maslow.

<zoom-img src="/medium/img/2feb64992e54/image-02.png" alt="Jerarquía de objetivos de programación" width="100%"></zoom-img>

Usar literales favorece el primer nivel, la comodidad al escribir. Pero
no alcanza el nivel más alto: la capacidad de modificar el sistema con
seguridad.

``` js
invoice.setState('pending');
order.setState('pending');
```

Es cómodo, pero al buscar todos los estados `pending` de pedidos se
mezclarán con los de facturas. La importación y el uso de símbolos
evitan justamente esa ambigüedad.

En [mi código
JavaScript](https://github.com/teqfw/core/blob/1af0e85783e95fbbbdee82a8b116eb17e9bc34a5/src/Shared/Enum/Sphere.mjs)
uso espacios de nombres inspirados en Zend1:

``` js
const TeqFw_Core_Shared_Enum_Sphere = {
  BACK: 'BACK', FRONT: 'FRONT', SHARED: 'SHARED',
};
Object.freeze(TeqFw_Core_Shared_Enum_Sphere);
export default TeqFw_Core_Shared_Enum_Sphere;
```

Al usarlo, incorporo la enumeración mediante [inyección de
dependencias](https://github.com/teqfw/web/blob/441d166c8cea10cbc70f649bcca6df008c24c431/src/Back/App/Server/Handler/Config/A/Di.mjs#L30)
y JSDoc:

``` js
export default function ({ TeqFw_Core_Shared_Enum_Sphere$: SPHERE }) {
  if (one.sphere === SPHERE.FRONT || one.sphere === SPHERE.SHARED) {
    // ...
  }
}
```

Así una búsqueda de texto encuentra todos los usos de
`TeqFw_Core_Shared_Enum_Sphere`, y JSDoc ayuda al IDE a localizar cada
valor. JavaScript no prohíbe usar literales directamente; es
responsabilidad del programador usar las herramientas con criterio.
Aunque `enum` no esté implementado realmente en JavaScript, considero
útil escribir como si lo estuviera.
