Estoy reconstruyendo un antiguo proyecto Java en Javascript, y me di cuenta de que no hay una buena manera de hacer enumeraciones en JS.
Lo mejor que se me ocurre es:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
El const
guarda Colors
de ser reasignado, y la congelación impide que la mutación de las claves y valores. Estoy usando Símbolos para que Colors.RED
no sea igual a 0
, ni nada más aparte de sí mismo.
¿Hay algún problema con esta formulación? ¿Hay una mejor manera?
(Sé que esta pregunta se repite un poco, pero todas las preguntas y respuestas anteriores son bastante antiguas y ES6 nos brinda algunas capacidades nuevas).
EDITAR:
Otra solución, que trata el problema de la serialización, pero creo que todavía tiene problemas de dominio:
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
Al utilizar referencias de objetos como valores, obtiene la misma prevención de colisiones que los símbolos.
fuente
JSON.stringify()
. No se puede serializar / deserializarSymbol
.Respuestas:
No veo ninguno
Colapsaría las dos declaraciones en una:
Si no le gusta la repetitiva, como las
Symbol
llamadas repetidas , también puede escribir una función auxiliarmakeEnum
que cree lo mismo a partir de una lista de nombres.fuente
Symbol.for
no , no tienen problemas de cross-reino, sin embargo, tiene el problema de colisión corriente con un espacio de nombres verdaderamente global .enum => ({[Colors.RED]: "bright red", [Colors.BLUE]: "deep blue", [Colors.GREEN]: "grass green"}[enum])
).Si bien el uso
Symbol
como el valor enum funciona bien para casos de uso simples, puede ser útil dar propiedades a las enumeraciones. Esto se puede hacer usando unObject
como el valor de enumeración que contiene las propiedades.Por ejemplo, podemos dar a cada uno
Colors
un nombre y un valor hexadecimal:La inclusión de propiedades en la enumeración evita tener que escribir
switch
declaraciones (y posiblemente olvidar nuevos casos en las instrucciones de cambio cuando se extiende una enumeración). El ejemplo también muestra las propiedades y tipos de enumeración documentados con la anotación de enumeración JSDoc .La igualdad funciona como se espera con
Colors.RED === Colors.RED
sertrue
yColors.RED === Colors.BLUE
serfalse
.fuente
Como se mencionó anteriormente, también podría escribir una
makeEnum()
función auxiliar:Úselo así:
fuente
const makeEnum = (...lst) => Object.freeze(Object.assign({}, ...lst.map(k => ({[k]: Symbol(k)}))));
luego úsela comoconst colors = makeEnum("Red", "Green", "Blue")
Este es mi enfoque personal.
fuente
Comprueba cómo TypeScript lo hace . Básicamente hacen lo siguiente:
Usa símbolos, congela objetos, lo que quieras.
fuente
MAP[MAP[1] = 'A'] = 1;
lugar deMAP[1] = 'A'; MAP['A'] = 1;
. Siempre he escuchado que usar una tarea como expresión es un mal estilo. Además, ¿qué beneficio obtiene de las tareas reflejadas?MAP[MAP[1] = 'A'] = 1;
.x
sea un valor Enum válido al hacerloEnum[Enum[x]] === x
. No resuelve ninguno de mis problemas originales, pero podría ser útil y no rompe nada.Si no necesita un ES6 puro y puede usar el Script mecanografiado, tiene un buen
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
fuente
Puede consultar Enumify , una biblioteca muy buena y bien presentada para enumeraciones de ES6.
fuente
Tal vez esta solución? :)
Ejemplo:
fuente
Prefiero el enfoque de @ tonethar, con un poco de mejoras y excavaciones para el beneficio de comprender mejor los fundamentos del ecosistema ES6 / Node.js. Con un fondo en el lado del servidor de la cerca, prefiero el enfoque del estilo funcional alrededor de las primitivas de la plataforma, esto minimiza la hinchazón del código, la pendiente resbaladiza en el valle de administración de la sombra de la muerte del estado debido a la introducción de nuevos tipos y aumentos la legibilidad: deja más clara la intención de la solución y el algoritmo.
Solución con TDD , ES6 , Node.js , Lodash , Jest , Babel , ESLint
fuente
Array.from(Object.assign(args))
no hace absolutamente nada Podrías usar...args
directamente.Aquí está mi enfoque, incluidos algunos métodos de ayuda
-
fuente
También puede usar el paquete es6-enum ( https://www.npmjs.com/package/es6-enum ). Es muy fácil de usar. Vea el siguiente ejemplo:
fuente
Aquí está mi implementación de una enumeración de Java en JavaScript.
También incluí pruebas unitarias.
fuente
Podrías usar ES6 Map
fuente
const x = Object.freeze({key: 'value'})
en su lugar para obtener algo que se vea y se comporta como enum en ES6