2015-02-03 18 views
24

Gibt es eine Möglichkeit, die Notation ECMAScript6 class zu verwenden, um entweder eine statische Klassenvariable oder einen Standardwert für eine Instanzvariable zu deklarieren? Ohne class, was ich im Sinn haben würde alsMitgliedsvariablen in ES6-Klassen

function MyClass(arg) { if(arg) this.arg = arg; } 
MyClass.classVariable = 42; 
MyClass.prototype.arg = "no arg specified"; 
geschrieben werden

Die naheliegendste ES6 ähnliche Schreibweise meiner Meinung nach

gewesen wäre
class MyClass { 
    constructor(arg) { if(arg) this.arg = arg; } 
    static let classVariable = 42; 
    let arg = "no arg specified"; 
} 

Aber das funktioniert nicht, da the current spec draft nach dem Nur Produktionen von ClassElement sind statische und Instanzmethoden und Semikolons alle von selbst. OK, man kann ein Paar von Getter- und Setter-Methoden verwenden, um eine ähnliche Semantik zu erreichen, wie ich es skizziert habe, aber ich schätze, dass es eine starke Leistungseinbuße und eine wirklich bizarre Syntax gibt.

Gibt es einen Entwurf, der vorschlägt, Variablen in die Notation class einzuschließen, auf die eine oder andere Art? Wenn ja, wie war die vorgeschlagene Syntax, wo wurde sie veröffentlicht, wo wurde sie diskutiert, wie lief die Diskussion und wie ist der aktuelle Stand der Dinge an dieser Front? So wie es aussieht, kann diese Frage nicht beantwortet werden, wenn vorher auf keiner Ebene etwas darüber diskutiert wurde, aber ich halte das für unwahrscheinlich.

Ein bisschen Hintergrund: Ich spiele gerade mit dem Google Closure-Compiler, der eine erweiterte Kompilierung durchführt, mit ES6 als Eingabe. Damit das funktioniert, brauche ich einen Platz, um meine Typ-Annotationen für Member-Variablen zu platzieren, und ich habe sie mit der Syntax /** @type {string} */ MyClass.prototype.arg; platziert, was ein semantisches No-Op in ECMAScript ist, aber die Typinformationen für den Closure-Compiler schön und einfach bereitstellt. Ich habe noch keinen ähnlich schönen Weg gefunden, dies mit einem class Konstrukt zu tun. Aber wenn Sie diesen Aspekt ansprechen möchten, wäre das ein Kommentar. Bei der obigen Frage geht es um Mitgliedererklärungen, bei denen es sich um mehr als nur No-Ops handelt. Das sollten wir hier diskutieren.

+2

Ich denke 'class Foo {foo get() {return 123}}' so nah wie es wird – kangax

+0

Ich denke @ kangax Technik ist die beste Wette für alles, was als eine abstrakte Klasse fungieren wird. Ich hatte das gleiche Problem; Hier ist ein Controller, den ich geschrieben habe, der Ihnen vielleicht einige Ideen geben kann. Der Konstruktor der Basisklasse führt alle schweren Aufgaben für eine einzigartige Funktionalität aus (in diesem Fall das Zusammenführen von Arrays). Sie müssen also nur sicherstellen, dass 'super()' immer für Unterklassenkonstruktoren aufgerufen wird: https://github.com/ affirmix/wolframjs/blob/master/src/controller.js. Sie können sehen, dass Sub-Klassen nicht zu fies aussehen: https://github.com/affirmix/tungstenjs-todomvc/blob/master/src/todoitem-controller.j –

Antwort

29

ES6 wird fast sicher nicht die Syntax für die Definition von Klassenvariablen abdecken. Mit der Klassensyntax können nur Methoden und Getter/Setter definiert werden. Das bedeutet, dass Sie weiterhin die MyClass.classVariable = 42; Route für Klassenvariablen verwenden müssen.

Wenn Sie nur eine Klasse mit einigen Standardwerten initialisieren möchten, gibt es eine umfangreiche neue Syntax für die Standardwerte für Funktionsargumente und Destrukturierung, die Sie verwenden können. Um ein einfaches Beispiel zu geben:

class Foo { 
    constructor(foo = 123) { 
     this.foo = foo; 
    } 
} 

new Foo().foo == 123 
new Foo(42).foo == 42 
+0

Dieser Ansatz funktioniert nicht wirklich, wenn Sie Zugriff auf Klasseneigenschaften, die im Konstruktor in anderen Funktionen festgelegt sind. Siehe http://stackoverflow.com/questions/20279484/how-to-access-the-correct-this-context-inside-a-callback – Jacob

+0

@Jacob in dem Beispiel, das ich gab Ich setze keine Klasseneigenschaften im Konstruktor, sondern eine Instanzeigenschaft mit einem Standardwert. Wenn Sie jedoch innerhalb einer Funktion auf die Instanz auf eine Klasseneigenschaft zugreifen möchten, können Sie mit 'this.constructor.classProperty' darauf zugreifen. – lyschoening

+0

[Klassenkörper und Methodendefinitionen] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes#Class_body_and_method_definitions) hat den Abschnitt ** Prototype methods **. –

5

Ich habe nicht verwendet Google Closure Compiler, aber mit Babel können Sie erklären static (scoped zu einem class) Variablen wie beschrieben here. Der Artikel konzentriert sich auf React wegen des Nutzens von static Mitgliedern für React, ist aber allgemein auf ES6 class es anwendbar.

Syntax ist in der Nähe von Ihnen vorgeschlagenen Syntax:

class MyClass { 
    constructor(arg) { if(arg) this.arg = arg; } 
    static defaultArg = 42; 
    let arg = MyClass.defaultArg; 
} 

Beachten Sie, dass Sie 'es7.classProperties' zu Ihrem .babelrc dafür zu kompilieren hinzuzufügen haben. Weitere Informationen finden Sie unter Babel 5.0.0 release notes.

Ich weiß nicht, ob es einen Weg gibt, eine static als const zu erklären.

3

Obwohl es nicht Teil der ES6-Spezifikation ist, sieht es aus wie es bald kommt und wird bereits von Babel und einigen anderen unterstützt.

Hier ist die Spezifikation: https://github.com/jeffmo/es-class-fields-and-static-properties

und eine vollständige Liste aller Vorschläge und deren Status: https://github.com/tc39/ecma262

+0

"Das sieht aus, als ob es in ES7 kommt", ist es definitiv nicht, das Feature-Set ist finalisiert und besteht nur aus den 2 Stufe-4-Vorschlägen. – zerkms

+0

@zerkms du hast absolut recht, ich habe meine Antwort modifiziert, danke für die Korrektur! Ich wusste nicht, es7 wurde abgeschlossen. –

Verwandte Themen