Declarando constantes estáticas em classs ES6?

Eu quero implementar constantes em uma class , porque é onde faz sentido localizá-las no código.

Até agora, tenho implementado a seguinte solução alternativa com methods estáticos:

 class MyClass { static constant1() { return 33; } static constant2() { return 2; } // ... } 

Eu sei que existe a possibilidade de mexer com protótipos, mas muitos recomendam contra isso.

Existe uma maneira melhor de implementar constantes em classs ES6?

Veja algumas coisas que você poderia fazer:

Exportar uma const do módulo . Dependendo do seu caso de uso, você poderia simplesmente:

 export const constant1 = 33; 

E importe isso do módulo quando necessário. Ou, com base na sua ideia de método estático, você pode declarar um acessador static get :

 const constant1 = 33, constant2 = 2; class Example { static get constant1() { return constant1; } static get constant2() { return constant2; } } 

Dessa forma, você não precisará de parênteses:

 const one = Example.constant1; 

Exemplo REPL de Babel

Então, como você diz, uma vez que uma class é apenas açúcar sintático para uma function, você pode simplesmente adicionar uma propriedade não gravável da seguinte forma:

 class Example { } Object.defineProperty(Example, 'constant1', { value: 33, writable : false, enumerable : true, configurable : false }); Example.constant1; // 33 Example.constant1 = 15; // TypeError 

Pode ser bom se pudéssemos fazer algo como:

 class Example { static const constant1 = 33; } 

Mas, infelizmente, essa syntax de propriedade de class é apenas em uma proposta do ES7 e, mesmo assim, não permitirá adicionar const à propriedade.

Estou usando o babel e a seguinte syntax está funcionando para mim:

 class MyClass { static constant1 = 33; static constant2 = { case1: 1, case2: 2, }; // ... } MyClass.constant1 === 33 MyClass.constant2.case1 === 1 

Por favor, considere que você precisa do pré "stage-0" ajuste "stage-0" .
Para instalá-lo:

 npm install --save-dev babel-preset-stage-0 // in .babelrc { "presets": ["stage-0"] } 

Atualizar:

atualmente usa stage-2

Neste documento , afirma:

Não há (intencionalmente) nenhuma maneira declarativa direta de definir propriedades de propriedades de dados de protótipos (além de methods) ou propriedades de instâncias.

Isso significa que é intencionalmente assim.

Talvez você possa definir uma variável no construtor?

 constructor(){ this.key = value } 

Também é possível usar Object.freeze em seu object de function de class (es6) / construtor (es5) para torná-lo imutável:

 class MyConstants {} MyConstants.staticValue = 3; MyConstants.staticMethod = function() { return 4; } Object.freeze(MyConstants); // after the freeze, any attempts of altering the MyConstants class will have no result // (either trying to alter, add or delete a property) MyConstants.staticValue === 3; // true MyConstants.staticValue = 55; // will have no effect MyConstants.staticValue === 3; // true MyConstants.otherStaticValue = "other" // will have no effect MyConstants.otherStaticValue === undefined // true delete MyConstants.staticMethod // false typeof(MyConstants.staticMethod) === "function" // true 

Tentando alterar a class, você terá uma falha suave (não causará nenhum erro, simplesmente não terá efeito).

Como https://stackoverflow.com/users/2784136/rodrigo-botti disse, eu acho que você está procurando Object.freeze() . Aqui está um exemplo de uma class com estática imutável:

 class User { constructor(username, age) { if (age < User.minimumAge) { throw new Error('You are too young to be here!'); } this.username = username; this.age = age; this.state = 'active'; } } User.minimumAge = 16; User.validStates = ['active', 'inactive', 'archived']; deepFreeze(User); function deepFreeze(value) { if (typeof value === 'object' && value !== null) { Object.freeze(value); Object.getOwnPropertyNames(value).forEach(property => { deepFreeze(value[property]); }); } return value; } 
 class Whatever { static get MyConst() { return 10; } } let a = Whatever.MyConst; 

Parece funcionar para mim.

Você pode criar uma maneira de definir constantes estáticas em uma class usando um recurso ímpar de classs ES6. Como as statistics são herdadas por suas subclasss, você pode fazer o seguinte:

 const withConsts = (map, BaseClass = Object) => { class ConstClass extends BaseClass { } Object.keys(map).forEach(key => { Object.defineProperty(ConstClass, key, { value: map[key], writable : false, enumerable : true, configurable : false }); }); return ConstClass; }; class MyClass extends withConsts({ MY_CONST: 'this is defined' }) { foo() { console.log(MyClass.MY_CONST); } } 

Aqui está mais uma maneira de fazer

 /* one more way of declaring constants in a class, Note - the constants have to be declared after the class is defined */ class Auto{ //other methods } Auto.CONSTANT1 = "const1"; Auto.CONSTANT2 = "const2"; console.log(Auto.CONSTANT1) console.log(Auto.CONSTANT2);