estatica clases clase javascript class constants ecmascript-6

javascript - estatica - ¿Declarando constantes estáticas en las clases de ES6?



clase estatica javascript (9)

Quiero implementar constantes en una class , porque ahí es donde tiene sentido ubicarlas en el código.

Hasta ahora, he estado implementando la siguiente solución con métodos estáticos:

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

Sé que existe la posibilidad de jugar con los prototipos, pero muchos recomiendan no hacerlo.

¿Hay una mejor manera de implementar constantes en las clases de ES6?


¿Quizás solo ponga todas sus constantes en un objeto congelado?

class MyClass { constructor() { this.constants = Object.freeze({ constant1: 33, constant2: 2, }); } static get constant1() { return this.constants.constant1; } doThisAndThat() { //... let value = this.constants.constant2; //... } }


Aquí hay algunas cosas que puedes hacer:

Exportar una const desde el módulo . Dependiendo de su caso de uso, podría simplemente:

export const constant1 = 33;

E importe eso desde el módulo cuando sea necesario. O, basándose en su idea de método estático, podría declarar un get get static :

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

De esa manera, no necesitarás paréntesis:

const one = Example.constant1;

Ejemplo REPL de Babel

Luego, como usted dice, dado que una class es solo azúcar sintáctica para una función, puede agregar una propiedad no editable como esta:

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

Puede ser bueno si pudiéramos hacer algo como:

class Example { static const constant1 = 33; }

Pero desafortunadamente, esta sintaxis de propiedad de clase solo está en una propuesta de ES7, e incluso entonces no permitirá agregar const a la propiedad.


Aquí hay una manera más que puedes hacer

/* 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);

Nota: el orden es importante, no puede tener las constantes anteriores

Uso console.log (Auto.CONSTANT1);


Como dijo , creo que estás buscando Object.freeze() . Aquí hay un ejemplo de una clase con estática inmutable:

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; }


En este documento dice:

No existe (intencionalmente) una forma declarativa directa para definir propiedades de datos de prototipo (que no sean métodos) propiedades de clase o propiedad de instancia

Esto significa que es intencionalmente así.

¿Quizás puedas definir una variable en el constructor?

constructor(){ this.key = value }


Estoy usando babel y la siguiente sintaxis está funcionando para mí:

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

Tenga en cuenta que necesita el preajuste "stage-0" .
Para instalarlo:

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

Actualizar:

Actualmente uso stage-3


Puede crear una forma de definir constantes estáticas en una clase utilizando una característica extraña de las clases ES6. Dado que las subclases heredan las estadísticas, puede hacer lo siguiente:

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); } }


También es posible usar Object.freeze en su objeto class (es6) / constructor function (es5) para hacerlo inmutable:

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

Intentar alterar la clase te dará un fallo suave (no arrojará ningún error, simplemente no tendrá ningún efecto).


class Whatever { static get MyConst() { return 10; } } let a = Whatever.MyConst;

Parece funcionar para mi.