214 votes

Énums en Javascript avec ES6

Je suis à la reconstruction d'un vieux projet Java en Javascript, et se rendit compte qu'il n'y a pas de bonne façon de faire des enums en JS.

Le mieux que je puisse vous arriver, c'est:

const Colors = {
    RED: Symbol("red"),
    BLUE: Symbol("blue"),
    GREEN: Symbol("green")
};
Object.freeze(Colors);

L' const conserve Colors d'être réaffectés, et la congélation empêche la mutation des clés et des valeurs. Je suis à l'aide de Symboles, de sorte que Colors.RED n'est pas égal à 0, ou quoi que ce soit d'autre à part lui-même.

Est-il un problème avec cette formulation? Est-il un meilleur moyen?


(Je sais que cette question est un peu une répétition, mais tous les précédents Q/Comme sont assez anciennes, et ES6 nous donne quelques nouvelles fonctionnalités.)


EDIT:

Une autre solution, qui traite de la sérialisation de problème, mais je crois encore a realm questions:

const enumValue = (name) => Object.freeze({toString: () => name});

const Colors = Object.freeze({
    RED: enumValue("Colors.RED"),
    BLUE: enumValue("Colors.BLUE"),
    GREEN: enumValue("Colors.GREEN")
});

En utilisant des références à des objets comme les valeurs, vous obtenez le même pour éviter l'abordage par des Symboles.

207voto

Bergi Points 104242

Y a-t-il un problème avec cette formulation?

Je n'en vois pas.

Y a-t-il un meilleur moyen?

Je réduirais les deux déclarations en une seule:

 const Colors = Object.freeze({
    RED:   Symbol("red"),
    BLUE:  Symbol("blue"),
    GREEN: Symbol("green")
});
 

Si vous n'aimez pas le passe-partout, comme les appels répétés Symbol , vous pouvez bien sûr aussi écrire une fonction d'assistance makeEnum qui crée la même chose à partir d'une liste de noms.

43voto

polarisation Points 163

Lors de l'utilisation d' Symbol que la valeur d'enum fonctionne très bien pour une utilisation simple des cas, il peut être utile de donner des propriétés à des enums. Cela peut être fait en utilisant un Object que la valeur d'énumération contenant les propriétés.

Par exemple on peut donner à chacun de l' Colors un nom et une valeur hex:

/**
 * Enum for common colors.
 * @readonly
 * @enum {{name: string, hex: string}}
 */
const Colors = Object.freeze({
  RED:   { name: "red", hex: "#f00" },
  BLUE:  { name: "blue", hex: "#00f" },
  GREEN: { name: "green", hex: "#0f0" }
});

Y compris les propriétés de l'enum évite d'avoir à écrire switch des déclarations (et éventuellement l'oubli de nouveaux cas à l'interrupteur consolidés lorsqu'une enum est prolongé). L'exemple montre également l'énumération des propriétés et types documenté avec la JSDoc enum annotation.

L'égalité fonctionne comme prévu avec Colors.RED === Colors.RED être true, et Colors.RED === Colors.BLUE être false.

12voto

tonethar Points 1406

Comme mentionné ci-dessus, vous pouvez également écrire une fonction d'aide makeEnum() :

 function makeEnum(arr){
    let obj = {};
    for (let val of arr){
        obj[val] = Symbol(val);
    }
    return Object.freeze(obj);
}
 

Utilisez-le comme ceci:

 const Colors = makeEnum(["red","green","blue"]);
let startColor = Colors.red; 
console.log(startColor); // Symbol(red)

if(startColor == Colors.red){
    console.log("Do red things");
}else{
    console.log("Do non-red things");
}
 

7voto

givehug Points 608

Vérifiez comment TypeScript le fait . Fondamentalement, ils font ce qui suit:

 const MAP = {};

MAP[MAP[1] = 'A'] = 1;
MAP[MAP[2] = 'B'] = 2;

MAP['A'] // 1
MAP[1] // A
 

Utilisez des symboles, geler un objet, tout ce que vous voulez.

5voto

Emmanuel.B Points 51

Vous pouvez consulter Enumify , une très bonne bibliothèque pour les énumérations ES6.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X