Alternativas de variables de clase ES6
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 = true
hacerlo 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 ClassConfig
controlador y pase un parameter
objeto, que se declara por separado de la clase. Luego, el controlador se adjuntará a la clase. Estaba pensando en WeakMaps
integrarlo también, de alguna manera).
¿Qué tipo de ideas tendrías para manejar esta situación?
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
Solo para agregar a la respuesta de Benjamin: las variables de clase son posibles, pero no prototype
las 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.foo
decir da 'bar'
pero new MyClass().foo
esundefined
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.constructor
apunta hacia atrás X
. Cuando new
se 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.