Estou reconstruindo um projeto Java antigo em Javascript e percebi que não há uma boa maneira de criar enumerações em JS.
O melhor que posso apresentar é:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
Os const
mantimentos Colors
não são reatribuídos e o congelamento evita que as chaves e os valores sejam alterados. Estou usando símbolos para que Colors.RED
não seja igual a 0
, ou qualquer outra coisa além de si.
Existe algum problema com esta formulação? Existe uma maneira melhor?
(Eu sei que esta pergunta é um pouco repetida, mas todas as perguntas / respostas anteriores são bastante antigas e o ES6 nos oferece alguns novos recursos.)
EDITAR:
Outra solução, que lida com o problema de serialização, mas acredito que ainda tem problemas de domínio:
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
Ao usar referências de objeto como valores, você obtém a mesma prevenção de colisão que Símbolos.
fonte
JSON.stringify()
. Não é possível serializar / desserializarSymbol
.Respostas:
Eu não vejo nenhum.
Eu recolheria as duas instruções em uma:
Se você não gosta do clichê, como as
Symbol
chamadas repetidas , é claro que também pode escrever uma função auxiliarmakeEnum
que cria a mesma coisa a partir de uma lista de nomes.fonte
Symbol.for
não não tem problemas de cross-realm, no entanto, tem o problema de costume colisão com um namespace verdadeiramente global .enum => ({[Colors.RED]: "bright red", [Colors.BLUE]: "deep blue", [Colors.GREEN]: "grass green"}[enum])
).Embora o uso
Symbol
como valor de enum funcione bem em casos de uso simples, pode ser útil fornecer propriedades para enumerações. Isso pode ser feito usando umObject
valor como enum que contém as propriedades.Por exemplo, podemos atribuir a cada
Colors
um um nome e valor hexadecimal:A inclusão de propriedades no enum evita a necessidade de escrever
switch
instruções (e possivelmente esquece novos casos nas instruções switch quando um enum é estendido). O exemplo também mostra as propriedades e tipos de enumeração documentados com a anotação de enumeração JSDoc .A igualdade funciona como esperado com o
Colors.RED === Colors.RED
sertrue
e oColors.RED === Colors.BLUE
serfalse
.fonte
Como mencionado acima, você também pode escrever uma
makeEnum()
função auxiliar:Use-o assim:
fonte
const makeEnum = (...lst) => Object.freeze(Object.assign({}, ...lst.map(k => ({[k]: Symbol(k)}))));
Em seguida, use-o comoconst colors = makeEnum("Red", "Green", "Blue")
Esta é a minha abordagem pessoal.
fonte
Veja como o TypeScript faz isso . Basicamente, eles fazem o seguinte:
Use símbolos, congele objetos, o que quiser.
fonte
MAP[MAP[1] = 'A'] = 1;
vez deMAP[1] = 'A'; MAP['A'] = 1;
. Eu sempre ouvi dizer que usar uma tarefa como expressão é um estilo ruim. Além disso, que benefício você obtém das atribuições espelhadas?MAP[MAP[1] = 'A'] = 1;
.x
é um valor válido de EnumEnum[Enum[x]] === x
. Ele não resolve nenhum dos meus problemas originais, mas pode ser útil e não quebra nada.Se você não precisa do ES6 puro e pode usar o Typescript, ele possui um bom
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
fonte
Você pode verificar o Enumify , uma biblioteca muito boa e com muitos recursos para enumerações do ES6.
fonte
Talvez esta solução? :)
Exemplo:
fonte
Prefiro a abordagem do @ tonethar, com algumas melhorias e escavações para o benefício de entender melhor os fundamentos do ecossistema ES6 / Node.js. Com um background no lado do servidor da cerca, eu prefiro a abordagem do estilo funcional em torno das primitivas da plataforma, isso minimiza o inchaço do código, a ladeira escorregadia no vale de gerenciamento do estado da sombra da morte devido à introdução de novos tipos e aumentos a legibilidade - deixa mais clara a intenção da solução e o algoritmo.
Solução com TDD , ES6 , Node.js , Lodash , Jest , Babel , ESLint
fonte
Array.from(Object.assign(args))
não faz absolutamente nada. Você poderia apenas usar...args
diretamente.Aqui está minha abordagem, incluindo alguns métodos auxiliares
-
fonte
você também pode usar o pacote es6-enum ( https://www.npmjs.com/package/es6-enum ). É muito fácil de usar. Veja o exemplo abaixo:
fonte
Aqui está minha implementação de uma enumeração Java em JavaScript.
Eu também incluí testes de unidade.
fonte
Você poderia usar o ES6 Map
fonte
const x = Object.freeze({key: 'value'})
para obter algo que pareça e se comporta como enum em ES6