Переменные-члены в классах ES6


Можно ли использовать нотацию ECMAScript6 class для объявления статической переменной класса или значения по умолчанию для переменной экземпляра? Без class то, что я имею в виду, было бы записано как

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

Наиболее очевидной ES6-подобной нотацией, на мой взгляд, была бы

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

Но это не работает, так как согласно текущему проекту спецификации единственными продуктами ClassElement являются статические и экземплярные методы и точки с запятой сами по себе. Хорошо, можно использовать пару методов геттера и сеттера, чтобы достичь сходной семантики с тем, что я описал, но я предполагаю, что это серьезный штраф за производительность и с действительно странным синтаксисом.

Есть ли какой-то проект, который предлагает включить переменные в нотацию class, так или иначе? Если да, то каков был предложенный синтаксис, где он был опубликован, где обсуждался, как проходила дискуссия и каково текущее положение дел на этом фронте? В нынешнем виде этот вопрос не может быть ответила, Если ничего подобного не обсуждалось ранее, на любом уровне, но я считаю это маловероятным.


Немного фона: в настоящее время я играю с компилятором закрытия Google, выполняющим расширенную компиляцию, используя ES6 в качестве входных данных. Чтобы это работало, мне нужно место, чтобы поместить мои аннотации типа для переменных-членов, и я использовал для их размещения синтаксис, подобный /** @type {string} */ MyClass.prototype.arg;, который является семантическим no-op в ECMAScript, но предоставляет информацию о типе компилятору закрытия красиво и легко. У меня нет и все же нашел такой же хороший способ сделать это с помощью конструкции class. Но если вы хотите обратиться к этому аспекту, это будет комментарий. Вопрос выше касается деклараций членов, которые больше, чем no-ops, так что это то, что ответ здесь должен обсудить.

3 26

3 ответа:

ES6 почти наверняка не будет охватывать синтаксис для определения переменных класса. С помощью синтаксиса класса можно определить только методы и геттеры / сеттеры. Это означает, что вам все равно придется пройти маршрут MyClass.classVariable = 42; для переменных класса.

Если вы просто хотите инициализировать класс с некоторыми значениями по умолчанию, вы можете использовать богатый новый синтаксис для аргументов функций и деструктурирующих значений по умолчанию. Приведу простой пример:

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

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

Я не использовал компилятор закрытия Google, но с Babel вы можете объявить static (область действия class) переменные, как описано здесь. Статья посвящена React из-за полезности членов static для React, но применима к ES6 classes в целом.

Синтаксис близок к вашему предлагаемому синтаксису:

class MyClass {
    constructor(arg) { if(arg) this.arg = arg; }
    static defaultArg = 42;
    let arg = MyClass.defaultArg;
}
Обратите внимание, что вам придется добавить 'es7.classProperties' к вашему .babelrc для компиляции. Дополнительную информацию смотрите в разделе Babel 5.0.0 release notes.

Я не знаю. узнайте, есть ли способ объявить static как const.

Хотя он не является частью спецификации ES6, похоже, что он скоро появится и уже поддерживается Babel и некоторыми другими.

Вот спецификация: https://github.com/jeffmo/es-class-fields-and-static-properties

И полный список всех предложений и их статус.: https://github.com/tc39/ecma262