2016-06-23 2 views
4

Я охотился вокруг, чтобы получить четкий ответ на этот вопрос, и большая часть всплывающих окон по-прежнему связана со старым (или я должен сказать «традиционным») способом определения классы с использованием function.Современный способ создания статической или переменной класса для класса Javascript

Согласно this SO answer,

Свойства класса не поддерживаются в ES2015.

Насколько я могу сказать, единственный способ, чтобы добавить статическую переменную в класс, как:

https://jsfiddle.net/abalter/fknwx3n4/

class C { 

    constructor(x) { 
    console.log("in constructor " + x); 
    this.x = x; 
    this.add(this.x); 
    } 

    add(x) { 
    console.log("in add " + x); 
    C.alist.push(x); 
    } 

    show() { 
    console.log("in show"); 
    console.log(C.alist); 
    } 
} 

// MUST be done outside of actual class definition. 
C.alist = []; 

c1 = new C(5); 
c1.show(); 
c2 = new C(10); 
c1.show(); 
c2.show(); 

Является ли это конец истории? Просто кажется странным, что он не сможет сделать это ВНУТРИ определения класса.

+0

Да, это конец истории. Нет ничего плохого в том, чтобы поместить такие свойства после определения класса, btw – Bergi

+0

ES7 поддерживает свойства класса. Но нет, это не конец истории в ES2015. Массив может быть установлен в конструкторе как свойство экземпляра. – undefined

+0

Ваш пример использования случай странный. Переменные статические свойства являются экземпляром одностороннего антипаттера. – Bergi

ответ

1

Вы можете вызвать статическую функцию, которая инициализирует все статические члены сразу после определения класса, а затем дополнительно удаляет эту функцию. (Возможно, функция статичных переменных может быть сгенерирована?)

Это позволит вам сохранить все ваши статические переменные внутри декларации класса.

class C { 
    static init() { 
    C.alist = []; 
    } 

    constructor(x) {…} 
    add(x) {…} 
    show() {…} 
} 
C.init(); 
delete C.init; 

Другим вариантом является, чтобы инициализировать статические переменные в конструктор, но это требует, чтобы по меньшей мере один объект быть создан до того, как статические переменные могут быть использованы.

class C { 
    constructor(x) { 
    C.alist = C.alist || []; 
    … 
    } 
    add(x) {…} 
    show() {…} 
} 
+0

Интересно ... Также немного неудобно, но, по крайней мере, это в конструкторе. – abalter

+0

@abalter Я обновил. Может быть, вы найдете этот другой вариант менее неудобным? Это также позволило бы *** *** установить все статические переменные позже. – 4castle

+0

Я бы закодировал 'this.alist = []', а не 'C.alist = []'. Почему экземпляры должны иметь одну и ту же информацию? Это неправильное использование класса. – undefined

0

Если все, что вы заботитесь о стилистической инкапсуляции класса и его статических свойств в одной структуре, вы должны рассмотреть возможность использования шаблона модуля (так же, как we used it in ES5 вложить конструктор и прототип).

В ES6, есть также Object.assign, что вы могли бы использовать для этого:

const C = Object.assign(class { 
    constructor() { 
     … 
    } 
    methods() { … } 
    … 
}, { 
    of(x) { … }, 
    static_methods() {…}, 
    … 
    static_property: … 
}); 
+0

У меня смешанные чувства. Он работает и даже позволяет разделить проблемы до степени, но теряет большую часть синтаксического сахара. Устраняется ли какое-либо из наших решений при расширении класса? – 4castle

+0

Нет, вы все равно можете использовать 'extends C' без проблем. Единственный синтаксический сахар, который вы теряете, является 'супер', когда вы ставите свои статические методы в литерал объекта, вам нужно использовать' static static_method() {super ...} 'для тела класса. – Bergi

+0

В случае, если кто-либо заботится, это смутно напоминает образец, используемый Эмбером с помощью 'reopenClass'. –

Смежные вопросы