Ich mache eine Javascript-Klasse und möchte ein öffentliches statisches Feld wie in Java haben. Dies ist der relevante Code:
export default class Agent {
CIRCLE: 1,
SQUARE: 2,
...
Dies ist der Fehler, den ich bekomme:
line 2, col 11, Class properties must be methods. Expected '(' but instead saw ':'.
Es sieht so aus, als ob ES6-Module dies nicht zulassen. Gibt es eine Möglichkeit, das gewünschte Verhalten zu erreichen, oder muss ich einen Getter schreiben?
javascript
ecmascript-6
aebabis
quelle
quelle
Antworten:
Sie erstellen ein "öffentliches statisches Feld" mit dem Accessor und einem "statischen" Schlüsselwort:
Wenn Sie sich eine Spezifikation ansehen , 14.5 - Klassendefinitionen - würden Sie etwas verdächtig Relevantes sehen :)
Von dort aus können Sie 14.5.14 - Laufzeitsemantik: ClassDefinitionEvaluation - folgen, um zu überprüfen, ob es wirklich das tut, wie es aussieht. Insbesondere Schritt 20:
IsStatic wurde bereits in 14.5.9 definiert
Wird
PropertyMethodDefinition
also mit "F" (Konstruktor, Funktionsobjekt) als Argument aufgerufen, wodurch wiederum eine Zugriffsmethode für dieses Objekt erstellt wird .Dies funktioniert bereits in mindestens IETP (Tech Preview) sowie in 6to5- und Traceur-Compilern.
quelle
unsafe.enable_getters_and_setters=true
Ihrer .flowconfig unter eine Zeile hinzufügen müssen[options]
(was ärgerlich ist).Es gibt einen ECMAScript-Vorschlag der Stufe 3 mit dem Titel "Static Class Features" von Daniel Ehrenberg und Jeff Morrison, mit dem dieses Problem gelöst werden soll. Zusammen mit dem Vorschlag für Stufe 3 "Klassenfelder" sieht der zukünftige Code folgendermaßen aus:
Das Obige entspricht:
Babel unterstützt das Transpilieren von Klassenfeldern über @ babel / plugin-comment-class-properties (in der Voreinstellung für Stufe 3 enthalten ), sodass Sie diese Funktion auch dann verwenden können, wenn Ihre JavaScript-Laufzeit dies nicht unterstützt.
Im Vergleich zu @ kangax 'Lösung, einen Getter zu deklarieren, kann diese Lösung auch leistungsfähiger sein, da hier direkt auf die Eigenschaft zugegriffen wird, anstatt eine Funktion aufzurufen.
Wenn dieser Vorschlag angenommen wird, kann JavaScript-Code auf eine Weise geschrieben werden, die herkömmlichen objektorientierten Sprachen wie Java und C♯ ähnlicher ist.
Bearbeiten : Ein Vorschlag für einheitliche Klassenfelder befindet sich jetzt in Phase 3. Update auf Babel v7.x-Pakete.
Bearbeiten (Februar 2020) : Die statischen Klassenfunktionen wurden in einen anderen Vorschlag aufgeteilt. Danke @ GOTO0!
quelle
In aktuellen Entwürfen von ECMAScript 6 (Stand Februar 2015) müssen alle Klasseneigenschaften Methoden und keine Werte sein (beachten Sie, dass in ECMAScript eine "Eigenschaft" im Konzept einem OOP-Feld ähnlich ist, außer dass der Feldwert ein
Function
Objekt sein muss, kein Objekt anderer Wert wie aNumber
oderObject
).Sie können diese weiterhin mit herkömmlichen ECMAScript-Konstruktoreigenschaftsspezifizierern angeben:
quelle
class
Syntax ohnehin nur syntaktischer Zucker für traditionelle JS-Konstruktorfunktionen und -Prototypen ist.enum
).class
Syntax auch gewisse nuancierte Unterschiede. Zum Beispiel erklärt ein Verfahren , mitClass.prototype.method = function () {};
ist enumerable (sichtbar mit for-Schleifen in), währendclass
Methoden nicht zählbare sind.Um die statische Variable voll auszunutzen, folgte ich diesem Ansatz. Um genauer zu sein, können wir es verwenden, um private Variablen zu verwenden oder nur einen öffentlichen Getter zu haben oder um sowohl Getter als auch Setter zu haben. Im letzten Fall entspricht es einer der oben aufgeführten Lösungen.
Ich könnte eine weitere Klasse erstellen, die Url erweitert, und es hat funktioniert.
Ich habe babel verwendet, um meinen ES6-Code in ES5 zu konvertieren
quelle
class Url { static getQueries… }; Url.staticMember = [];
viel einfacher gewesen?===
Vergleiche ergebenfalse
übrigensDie Antwort von @kangax ahmt nicht das gesamte statische Verhalten traditioneller OOP-Sprachen nach, da Sie nicht über die Instanz wie auf die statische Eigenschaft zugreifen können
const agent = new Agent; agent.CIRCLE; // Undefined
Wenn Sie wie bei OOPs auf statische Eigenschaften zugreifen möchten, ist hier meine Lösung:
Testcode wie folgt.
quelle
static
Feld durch eine Instanz wäre eher ungewöhnlich, oder? In einigen Sprachen, wie z. B. Java, geben IDEs tatsächlich eine Warnung / einen Hinweis aus, wenn Sie so etwas tun.