Ich habe ein altes Java-Projekt in Javascript neu erstellt und festgestellt, dass es in JS keine gute Möglichkeit gibt, Aufzählungen durchzuführen.
Das Beste, was ich mir einfallen lassen kann, ist:
const Colors = {
RED: Symbol("red"),
BLUE: Symbol("blue"),
GREEN: Symbol("green")
};
Object.freeze(Colors);
Das const
hält Colors
von neu zugewiesen wird, und das Einfrieren es verhindert , dass die Schlüssel und Werte mutiert. Ich benutze Symbole, damit das Colors.RED
nicht gleich ist 0
, oder irgendetwas anderes außer sich selbst.
Gibt es ein Problem mit dieser Formulierung? Gibt es einen besseren Weg?
(Ich weiß, dass diese Frage ein bisschen wiederholt wird, aber alle vorherigen Fragen und Antworten sind ziemlich alt, und ES6 bietet uns einige neue Funktionen.)
BEARBEITEN:
Eine andere Lösung, die sich mit dem Serialisierungsproblem befasst, aber meiner Meinung nach immer noch Probleme mit dem Bereich hat:
const enumValue = (name) => Object.freeze({toString: () => name});
const Colors = Object.freeze({
RED: enumValue("Colors.RED"),
BLUE: enumValue("Colors.BLUE"),
GREEN: enumValue("Colors.GREEN")
});
Durch die Verwendung von Objektreferenzen als Werte erhalten Sie die gleiche Kollisionsvermeidung wie bei Symbolen.
quelle
JSON.stringify()
. Kann nicht serialisieren / deserialisierenSymbol
.Antworten:
Ich sehe keine.
Ich würde die beiden Aussagen zu einer zusammenfassen:
Wenn Ihnen das Boilerplate nicht gefällt, wie die wiederholten
Symbol
Aufrufe, können Sie natürlich auch eine Hilfsfunktion schreibenmakeEnum
, die dasselbe aus einer Liste von Namen erstellt.quelle
Symbol.for
gibt keine bereichsübergreifenden Probleme, es gibt jedoch das übliche Kollisionsproblem mit einem wirklich globalen Namespace .enum => ({[Colors.RED]: "bright red", [Colors.BLUE]: "deep blue", [Colors.GREEN]: "grass green"}[enum])
).Während die Verwendung
Symbol
als Aufzählungswert für einfache Anwendungsfälle gut funktioniert, kann es nützlich sein, Aufzählungen Eigenschaften zuzuweisen. Dies kann durch Verwendung vonObject
als Aufzählungswert erfolgen, der die Eigenschaften enthält.Zum Beispiel können wir jedem
Colors
einen Namen und einen Hex-Wert geben:Durch das Einfügen von Eigenschaften in die Aufzählung wird vermieden, dass
switch
Anweisungen geschrieben werden müssen (und möglicherweise werden neue Fälle für die switch-Anweisungen vergessen, wenn eine Aufzählung erweitert wird). Das Beispiel zeigt auch die Enum-Eigenschaften und -Typen, die mit der JSDoc-Enum-Annotation dokumentiert sind .Gleichheit funktioniert wie erwartet mit
Colors.RED === Colors.RED
Seintrue
undColors.RED === Colors.BLUE
Seinfalse
.quelle
Wie oben erwähnt, können Sie auch eine
makeEnum()
Hilfsfunktion schreiben :Verwenden Sie es so:
quelle
const makeEnum = (...lst) => Object.freeze(Object.assign({}, ...lst.map(k => ({[k]: Symbol(k)}))));
const colors = makeEnum("Red", "Green", "Blue")
Dies ist mein persönlicher Ansatz.
quelle
Überprüfen Sie, wie TypeScript das macht . Grundsätzlich machen sie Folgendes:
Verwenden Sie Symbole, frieren Sie Objekte ein, was immer Sie wollen.
quelle
MAP[MAP[1] = 'A'] = 1;
stattMAP[1] = 'A'; MAP['A'] = 1;
. Ich habe immer gehört, dass die Verwendung einer Aufgabe als Ausdruck ein schlechter Stil ist. Welchen Nutzen ziehen Sie aus den gespiegelten Aufgaben?MAP[MAP[1] = 'A'] = 1;
.x
ein gültiger Enum-Wert istEnum[Enum[x]] === x
. Es löst keines meiner ursprünglichen Probleme, könnte aber nützlich sein und nichts kaputt machen.Wenn Sie kein reines ES6 benötigen und Typescript verwenden können, hat es Folgendes
enum
:https://www.typescriptlang.org/docs/handbook/enums.html
quelle
Sie können Enumify überprüfen , eine sehr gute und gut ausgestattete Bibliothek für ES6-Enums.
quelle
Vielleicht diese Lösung? :) :)
Beispiel:
quelle
Ich bevorzuge den Ansatz von @ tonethar, mit ein paar Verbesserungen und Ausgrabungen, um die Grundlagen des ES6 / Node.js-Ökosystems besser zu verstehen. Mit einem Hintergrund auf der Serverseite des Zauns bevorzuge ich den Ansatz des funktionalen Stils um die Grundelemente der Plattform herum. Dies minimiert das Aufblähen des Codes, den rutschigen Abhang in das Managementtal des Staates im Schatten des Todes aufgrund der Einführung neuer Typen und Erhöhungen die Lesbarkeit - macht die Absicht der Lösung und des Algorithmus klarer.
Lösung mit TDD , ES6 , Node.js , Lodash , Jest , Babel , ESLint
quelle
Array.from(Object.assign(args))
macht absolut nichts. Sie könnten einfach...args
direkt verwenden.Hier ist mein Ansatz, einschließlich einiger Hilfsmethoden
- -
quelle
Sie können auch das es6-enum-Paket verwenden ( https://www.npmjs.com/package/es6-enum ). Es ist sehr einfach zu bedienen. Siehe das folgende Beispiel:
quelle
Hier ist meine Implementierung einer Java-Aufzählung in JavaScript.
Ich habe auch Unit-Tests eingeschlossen.
quelle
Sie können ES6 Map verwenden
quelle
const x = Object.freeze({key: 'value'})
stattdessen, um etwas zu erhalten, das aussieht und aussieht verhält sich wie Enum in ES6