Quelle est la syntaxe préférée pour définir les énumérations en JavaScript? Quelque chose comme:
my.namespace.ColorEnum = {
RED : 0,
GREEN : 1,
BLUE : 2
}
// later on
if(currentColor == my.namespace.ColorEnum.RED) {
// whatever
}
Ou existe-t-il un idiome plus préférable?
javascript
syntax
enums
David Citron
la source
la source
0
comme numéro d'énumération. À moins qu'il ne soit utilisé pour quelque chose qui n'a pas été défini. JS les traitefalse || undefined || null || 0 || "" || '' || NaN
tous comme la même valeur lorsqu'ils sont comparés à l'aide==
.0 == null
renvoie fauxfalse == 0
et+null == 0
(et les conversions en nombres se produisent parfois lorsque vous ne vous y attendez pas), tandis quenull == undefined
trop, et+undefined
c'estNaN
(cependantNaN != NaN
).Réponses:
Depuis la version 1.8.5, il est possible de sceller et de geler l'objet, définissez donc ce qui précède comme:
ou
et le tour est joué! JS énumère.
Cependant, cela ne vous empêche pas d'attribuer une valeur indésirable à une variable, ce qui est souvent l'objectif principal des énumérations:
Une façon d'assurer un degré plus élevé de sécurité de type (avec des énumérations ou autre) consiste à utiliser un outil comme TypeScript ou Flow .
La source
Les citations ne sont pas nécessaires mais je les ai gardées pour plus de cohérence.
la source
var DaysEnum = Object.freeze ({ monday: {}, tuesday: {}, ... });
. Vous n'avez pas besoin de spécifier un identifiant, vous pouvez simplement utiliser un objet vide pour comparer les énumérations.if (incommingEnum === DaysEnum.monday) //incommingEnum is monday
if (Object.freeze) { Object.freeze(DaysEnum); }
({ monday: {},
etc. signifie que si vous convertissez cet objet en JSON via stringify, vous obtiendrez[{"day": {}}]
ce qui ne fonctionnera pas.var DaysEnum = {"monday":1, "tuesday":2, "wednesday":3, ...}
. Comparer des objets comme dans mon commentaire précédent est BEAUCOUP PLUS LENT que de comparer des nombres.Ce n'est pas vraiment une réponse, mais je dirais que ça marche très bien, personnellement
Cela dit, comme peu importe les valeurs (vous avez utilisé 0, 1, 2), j'utiliserais une chaîne significative au cas où vous voudriez sortir la valeur actuelle.
la source
Object.freeze()
. Cela empêchera tout autre code de modifier les valeurs de l'énumération. Exemple:var ColorEnum = Object.freeze({RED: 0, GREEN: 1, BLUE: 2});
instanceof
vérifications. Par exempleColorEnum.RED instanceof ColorEnum
(retournetrue
). Vous pouvez également résoudre une instance à partir d'un nomColorEnum.fromName("RED") === ColorEnum.RED
(retournetrue
). Chaque instance a également.name()
une.ordinal()
méthode et une , et l'énumération elle-même a unevalues()
méthode qui retourne un tableau de toutes les constantes.ToString()
méthode. Nous, les développeurs JS, sommes déjà trop dépendants des choses qui "fonctionnent"! En outre, on devrait pouvoir rapidementswitch
sur une énumération. La comparaison des chaînes est plus lente que la comparaison des nombres, vous obtiendrez donc desswitch
performances légèrement inférieures si vous utilisez des chaînes au lieu d'entiers.MISE À JOUR
Merci pour tous les votes positifs, mais je ne pense pas que ma réponse ci-dessous soit la meilleure façon d'écrire des énumérations en JavaScript. Voir mon article de blog pour plus de détails: énumère en JavaScript .
Alerter le nom est déjà possible:
Alternativement, vous pouvez créer des objets de valeurs, vous pouvez donc avoir le gâteau et le manger aussi:
En JavaScript, comme il s'agit d'un langage dynamique, il est même possible d'ajouter des valeurs d'énumération à l'ensemble plus tard:
N'oubliez pas que les champs de l'énumération (valeur, nom et code dans cet exemple) ne sont pas nécessaires pour le contrôle d'identité et ne sont là que pour des raisons de commodité. De plus, le nom de la propriété size elle-même n'a pas besoin d'être codé en dur, mais peut également être défini dynamiquement. En supposant que vous ne connaissiez que le nom de votre nouvelle valeur d'énumération, vous pouvez toujours l'ajouter sans problème:
Bien sûr, cela signifie que certaines hypothèses ne peuvent plus être faites (cette valeur représente l'ordre correct pour la taille par exemple).
N'oubliez pas qu'en JavaScript, un objet est comme une carte ou une table de hachage . Un ensemble de paires nom-valeur. Vous pouvez les parcourir ou autrement les manipuler sans en savoir beaucoup à leur sujet à l'avance.
Exemple
Et au fait, si vous êtes intéressé par les espaces de noms, vous voudrez peut-être jeter un œil à ma solution pour la gestion simple mais puissante des espaces de noms et des dépendances pour JavaScript: Packages JS
la source
Conclusion: vous ne pouvez pas.
Vous pouvez le simuler, mais vous n'obtiendrez pas de sécurité de type. En règle générale, cela se fait en créant un simple dictionnaire de valeurs de chaîne mappées sur des valeurs entières. Par exemple:
Le problème avec cette approche? Vous pouvez accidentellement redéfinir votre énumérateur, ou avoir accidentellement des valeurs d'énumérateur en double. Par exemple:
Éditer
Absolument,
Object.freeze
réglerait totalement le problème dont je me plaignais. Je voudrais rappeler à tout le monde que lorsque j'ai écrit ce qui précède,Object.freeze
n'existait pas vraiment.Maintenant ... maintenant, cela ouvre des possibilités très intéressantes.
Edit 2
Voici une très bonne bibliothèque pour créer des énumérations.
http://www.2ality.com/2011/10/enums.html
Bien qu'il ne corresponde probablement pas à toutes les utilisations valides des énumérations, il va très loin.
la source
var daysEnum = (function(){ var daysEnum = { monday: 1, tuesday: 2 }; return { get: function(value){ return daysEnum[value]; } } })(); daysEnum.get('monday'); // 1
Voici ce que nous voulons tous:
Vous pouvez maintenant créer vos énumérations:
En faisant cela, les constantes peuvent être accédées de la manière habituelle (YesNo.YES, Color.GREEN) et elles obtiennent une valeur int séquentielle (NO = 0, YES = 1; RED = 0, GREEN = 1, BLUE = 2).
Vous pouvez également ajouter des méthodes, en utilisant Enum.prototype:
Edit - petite amélioration - maintenant avec varargs: (malheureusement cela ne fonctionne pas correctement sur IE: S ... devrait alors rester avec la version précédente)
la source
Dans la plupart des navigateurs modernes, il existe un type de données primitif de symbole qui peut être utilisé pour créer une énumération. Il assurera la sécurité du type de l'énumération car chaque valeur de symbole est garantie par JavaScript comme étant unique, c'est-à-dire
Symbol() != Symbol()
. Par exemple:Pour simplifier le débogage, vous pouvez ajouter une description aux valeurs d'énumération:
Démo Plunker
Sur GitHub, vous pouvez trouver un wrapper qui simplifie le code requis pour initialiser l'énumération:
la source
Symbol
est destinée.Object.freeze
seulement pour les personnes qui n'ont pas accepté le fait que "monkeypatch à vos risques et périls" soit le contrat social de JS?toJSON
sur la classe contenant pour utiliser cette approche: stackoverflow.com/questions/58499828/…𝗣𝗹𝗮𝗶𝗻 𝗩𝗮𝗻𝗶𝗹𝗹𝗮𝗝𝗦 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲 𝗡𝗮𝗺𝗲𝘀
Passons directement au problème: la taille du fichier. Toutes les autres réponses répertoriées ici gonflent votre code à l'extrême. Je vous présente que pour les meilleures performances possibles, la lisibilité du code, la gestion de projet à grande échelle, la suggestion de syntaxe dans de nombreux éditeurs de code et la réduction de la taille du code par minification, c'est la bonne façon de faire les énumérations: les variables de notation de soulignement.
wvwvwvwvwvwvwvwvwvwvwvwvwvwvwvvvvwvwvwvv
Comme démontré dans le tableau ci-dessus et l'exemple ci-dessous, voici cinq étapes faciles pour commencer:
ENUM_
. Si indépendant ou côte à côte, utilisezINDEX_
.ENUM_
ouINDEX_
, puis le nom du groupe, puis un trait de soulignement, puis un nom convivial unique pour la propriétéENUMLENGTH_
,ENUMLEN_
,INDEXLENGTH_
ouINDEXLEN_
(siLEN_
ouLENGTH_
est de préférence personnelle) variables énumérées à la fin. Vous devez utiliser cette variable dans la mesure du possible dans votre code pour vous assurer que l'ajout d'une entrée supplémentaire à l'énumération et l'incrémentation de cette valeur ne cassera pas votre code.0
ne doit pas être utilisé comme une valeur énumérée parce que0 == null
,0 == false
,0 == ""
et d' autres JS folie. Je vous soumets que, pour éviter ce problème et booster les performances en même temps, utilisez toujours===
et ne laissez jamais==
apparaître dans votre code sauf avectypeof
(extypeof X == "string"
). Pendant toutes mes années d'utilisation===
, je n'ai jamais eu de problème avec l'utilisation de 0 comme valeur d'énumération. Si vous êtes toujours délicat, alors1
pourrait être utilisé comme valeur de départ dans lesENUM_
énumérations (mais pas dans lesINDEX_
énumérations) sans pénalité de performance dans de nombreux cas.Voici comment je me souviens quand utiliser
INDEX_
et quand utiliserENUM_
:Cependant,
ENUM_
peut, dans certaines circonstances, être approprié comme index, comme lors du comptage des occurrences de chaque élément.Observez que, dans le code ci-dessus, il est vraiment facile d'ajouter un nouveau type d'animal de compagnie: il vous suffira d'ajouter une nouvelle entrée
ENUM_PET_RAT
et de la mettre à jour enENUMLEN_PET
conséquence. Il pourrait être plus difficile et bogué d'ajouter une nouvelle entrée dans d'autres systèmes d'énumération.wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗘𝘅𝘁𝗲𝗻𝗱 𝗨𝗽𝗽𝗲𝗿𝗰𝗮𝘀𝗲 𝗩𝗮𝗿𝗶𝗮𝗯𝗹𝗲𝘀 𝗪𝗶𝘁𝗵 𝗔𝗱𝗱𝗶𝘁𝗶𝗼𝗻
De plus, cette syntaxe d'énumérations permet une extension de classe claire et concise comme indiqué ci-dessous. Pour étendre une classe, ajoutez un numéro d'incrémentation à l'
LEN_
entrée de la classe parente. Ensuite, terminez la sous-classe avec sa propreLEN_
entrée afin que la sous-classe puisse être étendue à l'avenir.(Longueur: 2 450 octets)
Certains diront peut-être que c'est moins pratique que d'autres solutions: il évite des tonnes d'espace, il prend beaucoup de temps à écrire et il n'est pas recouvert de syntaxe de sucre. Ces personnes auraient raison de ne pas minimiser leur code. Cependant, aucune personne raisonnable ne laisserait de code non minimisé dans le produit final. Pour cette minification, Closure Compiler est le meilleur que je n'ai pas encore trouvé. L'accès en ligne se trouve ici . Le compilateur de fermeture est capable de prendre toutes ces données d'énumération et de les incorporer, ce qui rend votre Javascript super petit et super rapide. Ainsi, Minify avec Closure Compiler. Observer.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗠𝗶𝗻𝗶𝗳𝘆 𝗪𝗶𝘁𝗵 𝗖𝗹𝗼𝘀𝘂𝗿𝗲 𝗖𝗼𝗺𝗽𝗶𝗹𝗲𝗿
Le compilateur de fermeture est capable d'effectuer des optimisations assez incroyables via des inférences qui dépassent largement les capacités de tout autre minifieur Javascript. Le compilateur de fermeture peut incorporer des variables primitives définies à une valeur fixe. Closure Compiler est également capable de faire des inférences sur la base de ces valeurs intégrées et d'éliminer les blocs inutilisés dans les instructions if et les boucles.
(Longueur: 605 octets)
Closure Compiler vous récompense pour un codage plus intelligent et une bonne organisation de votre code car, alors que de nombreux minificateurs punissent le code organisé avec une taille de fichier minifiée plus grande, Closure Compiler est capable de passer au crible toute votre propreté et votre santé mentale pour produire une taille de fichier encore plus petite si vous utilisez des astuces comme les énumérations de nom de variable. Dans cet esprit, c'est le Saint Graal du codage: un outil qui aide à la fois votre code avec une taille réduite et aide votre esprit en formant de meilleures habitudes de programmation.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗦𝗺𝗮𝗹𝗹𝗲𝗿 𝗖𝗼𝗱𝗲 𝗦𝗶𝘇𝗲
Voyons maintenant la taille du fichier équivalent sans aucune de ces énumérations.
Source sans utiliser d'énumérations (longueur: 1 973 octets (477 octets de moins que le code énuméré!))
Minifié sans utiliser d'énumérations (longueur: 843 octets (238 octets de plus que le code énuméré ))
Comme vu, sans énumérations, le code source est plus court au prix d'un code minifié plus grand. Je ne te connais pas; mais je sais avec certitude que je n'incorpore pas de code source dans le produit final. Ainsi, cette forme d'énumération est bien supérieure dans la mesure où elle se traduit par des tailles de fichier minifiées plus petites.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗖𝗼𝗼𝗽𝗲𝗿𝗮𝘁𝗶𝘃𝗲 🤝 𝗕𝘂𝗴 𝗙𝗶𝘅𝗶𝗻𝗴
Un autre avantage de cette forme d'énumération est qu'elle peut être utilisée pour gérer facilement des projets à grande échelle sans sacrifier la taille du code minifié. Lorsque vous travaillez sur un grand projet avec de nombreuses autres personnes, il peut être avantageux de marquer et d'étiqueter explicitement les noms de variable avec qui a créé le code afin que le créateur d'origine du code puisse être rapidement identifié pour la correction collaborative de bogues.
𝗦𝘂𝗽𝗲𝗿𝗶𝗼𝗿 𝗣𝗲𝗿𝗳𝗼𝗿𝗺𝗮𝗻𝗰𝗲
De plus, cette forme de dénombrement est également beaucoup plus rapide après minification. Dans les propriétés nommées normales, le navigateur doit utiliser des hashmaps pour rechercher où se trouve la propriété sur l'objet. Bien que les compilateurs JIT mettent en cache intelligemment cet emplacement sur l'objet, il y a encore une énorme surcharge due à des cas spéciaux tels que la suppression d'une propriété inférieure de l'objet.
Mais, avec les tableaux PACKED_ELEMENTS indexés en nombre entier non épars continus , le navigateur peut ignorer une grande partie de cette surcharge car l'index de la valeur dans le tableau interne est déjà spécifié. Oui, selon la norme ECMAScript, toutes les propriétés sont censées être traitées comme des chaînes. Néanmoins, cet aspect de la norme ECMAScript est très trompeur sur les performances car tous les navigateurs ont des optimisations spéciales pour les index numériques dans les tableaux.
Comparez le code ci-dessus au code ci-dessous.
On pourrait s'opposer au code avec des énumérations qui semblent être beaucoup plus longues que le code avec des objets ordinaires, mais les apparences peuvent être trompeuses. Il est important de se rappeler que la taille du code source n'est pas proportionnelle à la taille de sortie lors de l'utilisation du compilateur de fermeture épique. Observer.
Le code minifié sans énumérations est au-dessus et le code minifié avec énumérations est ci-dessous.
L'exemple ci-dessus montre qu'en plus d'avoir des performances supérieures, le code énuméré entraîne également une taille de fichier réduite plus petite.
wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗘𝗮𝘀𝘆 𝗗𝗲𝗯𝘂𝗴𝗴𝗶𝗻𝗴
De plus, la cerise sur le gâteau de celui-ci utilise cette forme d'énumération avec l' éditeur de texte CodeMirror en mode Javascript. Le mode de mise en évidence de la syntaxe Javascript de CodeMirror met en évidence les variables locales dans la portée actuelle. De cette façon, vous savez instantanément quand vous tapez correctement un nom de variable car si le nom de variable a été précédemment déclaré avec le
var
mot - clé, alors le nom de variable prend une couleur spéciale (cyan par défaut). Même si vous n'utilisez pas CodeMirror, au moins le navigateur lance un utile[variable name] is not defined
exception lors de l'exécution de code avec des noms d'énumération mal tapés. En outre, les outils JavaScript tels que JSLint et Closure Compiler sont très bruyants pour vous dire quand vous saisissez mal le nom d'une variable d'énumération. CodeMirror, le navigateur et divers outils Javascript réunis rendent le débogage de cette forme d'énumération très simple et très facile.Dans l'extrait ci-dessus, vous avez été alerté d'une erreur car il
ENUM_COLORENUM_DNE
n'existe pas.wvwwvw wvwvwvw wvwxvw wvwvwv vwvwvw wvwvvw wvwwvw wvwvwvw wvwvw wvwvwv vwvxwvw wvwvvw wvwwvw wvwvwwvwvv
𝗖𝗼𝗻𝗰𝗹𝘂𝘀𝗶𝗼𝗻 ☑
Je pense qu'il est prudent de dire que cette méthodologie d'énumération est en effet la meilleure voie à suivre non seulement pour la taille de code minifiée, mais aussi pour les performances, le débogage et la collaboration.
Après avoir lu une question utile, je remercie l'auteur d'avoir consacré du temps à son écriture en cliquant sur la flèche vers le haut en haut à gauche dans la zone de question. Chaque boîte de réponse a également l'une de ces flèches vers le haut.
la source
colors.REED
rendementsundefined
), donc les fautes de frappe créent des énigmes insaisissables. YEA ne fait pas de distinction entre l'utilisation des énumérations en tant qu'index et ID, ce qui entraîne une confusion dans le code où tout se ressemble. …J'ai joué avec ça, car j'aime mes énumérations. =)
En utilisant
Object.defineProperty
je pense avoir trouvé une solution quelque peu viable.Voici un jsfiddle: http://jsfiddle.net/ZV4A6/
En utilisant cette méthode .. vous devriez (en théorie) être capable d'appeler et de définir des valeurs d'énumération pour n'importe quel objet, sans affecter les autres attributs de cet objet.
En raison de l'attribut,
writable:false
cela devrait le rendre sûr.Vous devriez donc pouvoir créer un objet personnalisé, puis faire appel
Enum()
à lui. Les valeurs attribuées commencent à 0 et augmentent par élément.la source
return this;
à la fin d'Enum, vous pourriez faire:var EnumColors = {}.Enum('RED','BLUE','GREEN','YELLOW');
false
est la valeur par défaut pourwritable
,enumerable
etconfigurable
. Pas besoin de mâcher les défauts.Utiliser des proxys Javascript
TLDR: ajoutez cette classe à vos méthodes utilitaires et utilisez-la dans tout votre code, elle se moque du comportement Enum des langages de programmation traditionnels et génère en fait des erreurs lorsque vous essayez d'accéder à un énumérateur qui n'existe pas ou d'ajouter / mettre à jour un énumérateur. Pas besoin de compter
Object.freeze()
.Créez ensuite des énumérations en instanciant la classe:
Explication complète:
Une caractéristique très bénéfique des Enums que vous obtenez des langues traditionnelles est qu'elles explosent (provoquent une erreur de compilation) si vous essayez d'accéder à un énumérateur qui n'existe pas.
Outre le gel de la structure d'énumération simulée pour empêcher l'ajout accidentel / malveillant de valeurs supplémentaires, aucune des autres réponses ne traite de cette caractéristique intrinsèque d'énumérations.
Comme vous le savez probablement, l'accès aux membres non existants en JavaScript revient simplement
undefined
et ne fait pas exploser votre code. Étant donné que les énumérateurs sont des constantes prédéfinies (c'est-à-dire les jours de la semaine), il ne devrait jamais y avoir de cas où un énumérateur devrait être indéfini.Ne vous méprenez pas, le comportement de JavaScript de retour
undefined
lors de l'accès à des propriétés non définies est en fait une fonctionnalité très puissante du langage, mais ce n'est pas une fonctionnalité que vous souhaitez lorsque vous essayez de vous moquer des structures Enum traditionnelles.C'est là que les objets proxy brillent. Les procurations ont été normalisées dans la langue avec l'introduction de ES6 (ES2015). Voici la description de MDN:
Semblables à un proxy de serveur Web, les proxys JavaScript sont capables d'intercepter des opérations sur des objets (avec l'utilisation de "pièges", appelez-les hooks si vous le souhaitez) et vous permettent d'effectuer diverses vérifications, actions et / ou manipulations avant qu'elles ne se terminent (ou dans certains cas, arrêter complètement les opérations, ce qui est exactement ce que nous voulons faire si et quand nous essayons de référencer un énumérateur qui n'existe pas).
Voici un exemple artificiel qui utilise l'objet Proxy pour imiter les énumérations. Les énumérateurs dans cet exemple sont des méthodes HTTP standard (c'est-à-dire "GET", "POST", etc.):
HORS: Qu'est-ce que c'est qu'un proxy?
Je me souviens quand j'ai commencé à voir le mot proxy partout, cela n'avait définitivement aucun sens pour moi pendant longtemps. Si c'est vous en ce moment, je pense qu'un moyen facile de généraliser les procurations est de les considérer comme des logiciels, des institutions ou même des personnes qui agissent comme intermédiaires ou intermédiaires entre deux serveurs, sociétés ou personnes.
la source
valueOf
méthode par défaut en la spécifiant comme méthode d'instance sur la classe Enum. Cependant, pourquoi voulez-vous y accéder de cette façon par rapport à un simple accès par notation par points?logLevelEnum[settings.get("log_level")]
? l'ajoutparseOrThrow
serait simplement répétitif à ce que les pièges proxy font déjà pour vous.C'est un ancien que je connais, mais la façon dont il a depuis été implémenté via l'interface TypeScript est:
Cela vous permet de rechercher à la fois celui
MyEnum.Bar
qui renvoie 1 et celuiMyEnum[1]
qui renvoie "Bar" quel que soit l'ordre de déclaration.la source
enum MyEnum { Foo, Bar, Foobar }
Dans ES7 , vous pouvez faire un ENUM élégant en s'appuyant sur des attributs statiques:
puis
L'avantage (d'utiliser une classe au lieu d'un objet littéral) est d'avoir une classe parente
Enum
alors tous vos énumérations sera étend cette classe.la source
new ColorEnum()
n'a absolument aucun sens.Enum
a norme statique méthodes de recenseur sur elle, commegetValues()
,getNames()
,iterate()
, etc. Si tel est le cas, vous ne devez pas les réimplémenter pour chaque nouveau genreenum
.C'est la solution que j'utilise.
Et vous définissez vos énumérations comme ceci:
Et voici comment vous accédez à vos énumérations:
J'utilise généralement les 2 dernières méthodes pour mapper des énumérations à partir d'objets de message.
Quelques avantages de cette approche:
Quelques inconvénients:
la source
Créez un objet littéral:
la source
const
ne rend pas les propriétés de l'objet immuables, cela signifie seulement que la variableModes
ne peut pas être réaffectée à autre chose. Pour le rendre plus complet, utilisez-le àObject.freeze()
côtéconst
.Object.freeze
. Il empêche le compilateur de fermeture d'insérer l'objet.Si vous utilisez Backbone , vous pouvez obtenir gratuitement des fonctionnalités d'énumération complètes (rechercher par identifiant, nom, membres personnalisés) à l'aide de Backbone.Collection .
la source
vos réponses sont beaucoup trop compliquées
la source
J'ai modifié la solution d'André 'Fi':
Tester:
la source
J'ai proposé cette approche qui s'inspire des énumérations en Java. Celles-ci sont sécurisées et vous pouvez donc également effectuer des
instanceof
vérifications.Vous pouvez définir des énumérations comme ceci:
Days
fait maintenant référence à l'Days
énumération:La mise en oeuvre:
la source
freeze
méthode de compatibilité descendante? Par exemple,if (Object.freeze) { Object.freeze(values); }
IE8 ne prend pas en charge la méthode freeze ().
Source: http://kangax.github.io/compat-table/es5/ , cliquez sur "Afficher les navigateurs obsolètes?" en haut et vérifiez IE8 et geler l'intersection des colonnes de lignes.
Dans mon projet de jeu actuel, j'ai utilisé ci-dessous, car peu de clients utilisent encore IE8:
On pourrait aussi faire:
ou même ceci:
Le dernier semble le plus efficace pour la chaîne, il réduit votre bande passante totale si vous avez un serveur et un client échangeant ces données.
Bien sûr, il est maintenant de votre devoir de vous assurer qu'il n'y a pas de conflits dans les données (RE, EX, etc. doivent être uniques, également 1, 2, etc. doivent être uniques). Notez que vous devez les conserver indéfiniment pour une compatibilité descendante.
Affectation:
Comparaison:
la source
Vous n'avez pas besoin de vous assurer que vous n'attribuez pas de numéros en double à différentes valeurs d'énumération de cette façon. Un nouvel objet est instancié et affecté à toutes les valeurs d'énumération.
la source
Voici quelques façons d'implémenter les énumérations TypeScript .
Le moyen le plus simple consiste à simplement itérer sur un objet, en ajoutant des paires clé-valeur inversées à l'objet. Le seul inconvénient est que vous devez définir manuellement la valeur pour chaque membre.
Et voici un mixin lodash pour créer une énumération à l'aide d'une chaîne. Bien que cette version soit un peu plus impliquée, elle effectue automatiquement la numérotation pour vous. Toutes les méthodes lodash utilisées dans cet exemple ont un équivalent JavaScript normal, vous pouvez donc facilement les désactiver si vous le souhaitez.
la source
Je viens de publier un package NPM gen_enum vous permet de créer rapidement une structure de données Enum en Javascript:
Une chose intéressante à propos de ce petit outil est dans un environnement moderne (y compris les navigateurs nodejs et IE 9+) l'objet Enum retourné est immuable.
Pour plus d'informations, veuillez consulter https://github.com/greenlaw110/enumjs
Mises à jour
J'ai un
gen_enum
package obsolète et je fusionne la fonction dans le package constjs , qui fournit plus de fonctionnalités, y compris les objets immuables, la désérialisation des chaînes JSON, les constantes de chaîne et la génération de bitmap, etc. Consultez https://www.npmjs.com/package/constjs pour plus d'informations.Pour passer de
gen_enum
àconstjs
simplement changer la déclarationà
la source
Solution la plus simple:
Créer
Obtenez de la valeur
Obtenir la clé
la source
J'ai créé une classe Enum qui peut récupérer des valeurs ET des noms à O (1). Il peut également générer un tableau d'objets contenant tous les noms et valeurs.
Vous pouvez l'initier comme ceci:
Pour récupérer une valeur (comme Enums en C #):
Pour récupérer un nom pour une valeur (peut être ambigu lorsque vous mettez la même valeur pour des noms différents):
Pour obtenir un tableau avec chaque nom et valeur dans un objet:
Générera:
Vous pouvez également obtenir facilement les options de sélection html:
Qui tient:
la source
Même si seules les méthodes statiques (et non les propriétés statiques) sont prises en charge dans ES2015 (voir ici également, §15.2.2.2), vous pouvez curieusement utiliser ce qui suit avec Babel avec le
es2015
préréglage:J'ai trouvé que cela fonctionnait comme prévu, même entre les modules (par exemple, l'importation de l'
CellState
énumération à partir d'un autre module) et également lorsque j'importe un module à l'aide de Webpack.L'avantage de cette méthode sur la plupart des autres réponses est que vous pouvez l'utiliser avec un vérificateur de type statique (par exemple Flow ) et que vous pouvez affirmer, au moment du développement à l'aide de la vérification de type statique, que vos variables, paramètres, etc. sont du type
CellState
" enum "plutôt que d'autres énumérations (qui seraient impossibles à distinguer si vous utilisiez des objets ou des symboles génériques).mise à jour
Le code ci-dessus a une déficience en ce qu'il permet de créer des objets supplémentaires de type
CellState
(même si on ne peut pas les affecter aux champs statiques deCellState
car il est gelé). Pourtant, le code ci-dessous plus raffiné offre les avantages suivants:CellState
peut être crééla
values
fonction qui renvoie toutes les instances de l'énumération n'a pas à créer la valeur de retour de la manière ci-dessus, manuelle (et sujette aux erreurs).la source
manière es7, (itérateur, gel), utilisation:
code:
la source
Voici comment Typescript le traduit
enum
en Javascript:Maintenant:
Au début, je ne savais pas pourquoi
obj[1]
revenir'Active'
, mais je me suis ensuite rendu compte que son simple mort - L'opérateur d'affectation attribue une valeur, puis la renvoie:la source
Vous pouvez faire quelque chose comme ça
Comme défini dans cette bibliothèque. https://github.com/webmodule/foo/blob/master/foo.js#L217
Exemple complet https://gist.github.com/lnt/bb13a2fd63cdb8bce85fd62965a20026
la source
Un moyen rapide et simple serait:
la source
Au moment de la rédaction, octobre 2014 - voici donc une solution contemporaine. J'écris la solution en tant que module de nœud et j'ai inclus un test utilisant Mocha et Chai, ainsi que underscoreJS. Vous pouvez facilement les ignorer et prendre le code Enum si vous préférez.
Vu beaucoup de messages avec des bibliothèques trop compliquées, etc. La solution pour obtenir le support enum en Javascript est si simple qu'elle n'est vraiment pas nécessaire. Voici le code:
Fichier: enums.js
Et un test pour illustrer ce qu'il vous apporte:
fichier: enumsSpec.js
Comme vous pouvez le voir, vous obtenez une fabrique Enum, vous pouvez obtenir toutes les clés simplement en appelant enum.keys, et vous pouvez faire correspondre les clés elles-mêmes à des constantes entières. Et vous pouvez réutiliser l'usine avec différentes valeurs et exporter les énumérations générées en utilisant l'approche modulaire de Node.
Encore une fois, si vous n'êtes qu'un utilisateur occasionnel, ou dans le navigateur, etc., prenez simplement la partie d'usine du code, supprimant potentiellement la bibliothèque de soulignement si vous ne souhaitez pas l'utiliser dans votre code.
la source
C'est facile à utiliser, je pense. https://stackoverflow.com/a/32245370/4365315
MISE À JOUR:
Il y a mes codes d'assistance (
TypeHelper
).Afficher l'extrait de code
la source