Alternativas de variables de clase ES6

Resuelto wintercounter asked hace 10 años • 17 respuestas

Actualmente en ES5 muchos de nosotros estamos usando el siguiente patrón en frameworks para crear clases y variables de clase, lo cual es cómodo:

// ES 5
FrameWork.Class({

    variable: 'string',
    variable2: true,

    init: function(){

    },

    addItem: function(){

    }

});

En ES6 puedes crear clases de forma nativa, pero no hay ninguna opción para tener variables de clase:

// ES6
class MyClass {
    const MY_CONST = 'string'; // <-- this is not possible in ES6
    constructor(){
        this.MY_CONST;
    }
}

Lamentablemente, lo anterior no funcionará, ya que las clases sólo pueden contener métodos.

Entiendo que puedo this.myVar = truehacerlo constructor... pero no quiero "desechar" mi constructor, especialmente cuando tengo entre 20 y 30 parámetros o más para una clase más grande.

Estaba pensando en muchas formas de manejar este problema, pero todavía no he encontrado ninguna buena. (Por ejemplo: cree un ClassConfigcontrolador y pase un parameterobjeto, que se declara por separado de la clase. Luego, el controlador se adjuntará a la clase. Estaba pensando en WeakMapsintegrarlo también, de alguna manera).

¿Qué tipo de ideas tendrías para manejar esta situación?

wintercounter avatar Mar 20 '14 16:03 wintercounter
Aceptado

Actualización de 2018:

Ahora hay una propuesta de etapa 3; espero que esta respuesta quede obsoleta en unos meses.

Mientras tanto, cualquiera que utilice TypeScript o Babel puede utilizar la sintaxis:

varName = value

Dentro de un cuerpo de declaración/expresión de clase y definirá una variable. Con suerte, en unos meses/semanas podré publicar una actualización.

Actualización: Chrome 74 ahora viene con esta sintaxis funcionando.


Las notas en la wiki de ES para la propuesta en ES6 ( clases máximas y mínimas ) señalan:

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

Las propiedades de clase y las propiedades de datos de prototipo deben crearse fuera de la declaración.

A las propiedades especificadas en una definición de clase se les asignan los mismos atributos que si aparecieran en un objeto literal.

Esto significa que lo que estás pidiendo fue considerado y explícitamente decidido en contra.

¿pero por qué?

Buena pregunta. La buena gente de TC39 quiere declaraciones de clase para declarar y definir las capacidades de una clase. No sus miembros. Una declaración de clase ES6 define su contrato para su usuario.

Recuerde, una definición de clase define métodos prototipo ; definir variables en el prototipo generalmente no es algo que usted haga. Por supuesto, puedes utilizar:

constructor(){
    this.foo = bar
}

En el constructor como sugeriste. Véase también el resumen del consenso .

ES7 y más allá

Se está trabajando en una nueva propuesta para ES7 que permite variables de instancia más concisas a través de declaraciones y expresiones de clases - https://esdiscuss.org/topic/es7-property-initializers

Benjamin Gruenbaum avatar Apr 10 '2014 11:04 Benjamin Gruenbaum

Solo para agregar a la respuesta de Benjamin: las variables de clase son posibles, pero no prototypelas usarías para configurarlas.

Para una variable de clase verdadera, querrás hacer algo como lo siguiente:

class MyClass {}
MyClass.foo = 'bar';

Desde dentro de un método de clase se puede acceder a esa variable como this.constructor.foo(o MyClass.foo).

Por lo general, no se podría acceder a estas propiedades de clase desde la instancia de clase. es MyClass.foodecir da 'bar'pero new MyClass().fooesundefined

Si también desea tener acceso a su variable de clase desde una instancia, deberá definir adicionalmente un captador:

class MyClass {
    get foo() {
        return this.constructor.foo;
    }
}

MyClass.foo = 'bar';

Solo probé esto con Traceur, pero creo que funcionará igual en una implementación estándar.

JavaScript realmente no tiene clases . Incluso con ES6 estamos ante un lenguaje basado en objetos o prototipos en lugar de un lenguaje basado en clases. En ninguno function X () {}, X.prototype.constructorapunta hacia atrás X. Cuando newse utiliza el operador on X, se crea un nuevo objeto heredando X.prototype. Cualquier propiedad no definidaconstructor en ese nuevo objeto (incluido ) se busca desde allí. Podemos pensar en esto como generar propiedades de objetos y clases.

lyschoening avatar Jul 30 '2014 11:07 lyschoening