es7 - static class javascript
¿Por qué JavaScript ES6 no admite clases de múltiples constructores? (6)
Quiero escribir mi clase de Javascript como a continuación
No puede, de la misma manera que no puede sobrecargar funciones estándar como esa. Lo que puede hacer es usar el objeto arguments para consultar el número de argumentos pasados:
class Option {
constructor(key, value, autoLoad) {
// new Option()
if(!arguments.length) {
this.autoLoad = false;
}
// new Option(a, [b, [c]])
else {
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
}
Por supuesto (con su ejemplo actualizado), puede tomar el enfoque de que no le importa la cantidad de argumentos , sino de si se aprobó cada valor individual, en cuyo caso podría haber algo así como:
class Option {
constructor(key, value, autoLoad) {
if(!key) { // Could change this to a strict undefined check
this.autoLoad = false;
return;
}
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
Quiero escribir mi clase de Javascript como a continuación.
class Option {
constructor() {
this.autoLoad = false;
}
constructor(key, value) {
this[key] = value;
}
constructor(key, value, autoLoad) {
this[key] = value;
this.autoLoad = autoLoad || false;
}
}
Creo que sería bueno si podemos escribir clases de esta manera. Espere que suceda:
var option1 = new Option(); // option1 = {autoLoad: false}
var option2 = new Option(''foo'', ''bar'',); // option2 = {foo: ''bar''}
var option3 = new Option(''foo'', ''bar'', false); // option3 = {foo: ''bar'', autoLoad: false}
Adivinando de su código de muestra, todo lo que necesita es usar valores predeterminados para sus parámetros:
class Option {
constructor(key = ''foo'', value = ''bar'', autoLoad = false) {
this[key] = value;
this.autoLoad = autoLoad;
}
}
Habiendo dicho eso, otra alternativa a la sobrecarga de constructores es usar fábricas estáticas. Supongamos que le gustaría poder crear una instancia de un objeto a partir de parámetros simples, desde un hash que contenga esos mismos parámetros o incluso desde una cadena JSON:
class Thing {
constructor(a, b) {
this.a = a;
this.b = b;
}
static fromHash(hash) {
return new this(hash.a, hash.b);
}
static fromJson(string) {
return this.fromHash(JSON.parse(string));
}
}
let thing = new Thing(1, 2);
// ...
thing = Thing.fromHash({a: 1, b: 2});
// ...
thing = Thing.fromJson(''{"a": 1, "b": 2}'');
Aquí hay un truco para sobrecargar basado en arity (número de argumentos). La idea es crear una función a partir de una serie de funciones con aries diferentes (determinado mirando fn.length
).
function overloaded(...inputs) {
var fns = [];
inputs.forEach(f => fns[f.length] = f);
return function() {
return fns[arguments.length].apply(this, arguments);
};
}
var F = overloaded(
function(a) { console.log("function with one argument"); },
function(a, b) { console.log("function with two arguments"); }
);
F(1);
F(2, 3);
Por supuesto, esto necesita una gran cantidad de blindaje y limpieza, pero se entiende. Sin embargo, no creo que tengas mucha suerte aplicando esto a los constructores de la clase ES6, ya que son un caballo de un color diferente.
Lo que quieres se llama sobrecarga de constructor. Esto, y el caso más general de sobrecarga de funciones , no es compatible con ECMAScript.
ECMAScript no maneja los argumentos que faltan de la misma manera que los idiomas más estrictos. El valor de los argumentos faltantes se deja como undefined
lugar de generar un error. En este paradigma, es difícil / imposible detectar qué función sobrecargada está buscando.
La solución idiomática es tener una función y hacer que maneje todas las combinaciones de argumentos que necesita. Para el ejemplo original, puedes simplemente probar la presencia de la key
y el value
esta manera:
class Option {
constructor(key, value, autoLoad = false) {
if (typeof key !== ''undefined'') {
this[key] = value;
}
this.autoLoad = autoLoad;
}
}
Otra opción sería permitir que su constructor tome un objeto que esté vinculado a sus propiedades de clase:
class Option {
// Assign default values in the constructor object
constructor({key = ''foo'', value, autoLoad = true} = {}) {
this.key = key;
// Or on the property with default (not recommended)
this.value = value || ''bar'';
this.autoLoad = autoLoad;
console.log(''Result:'', this);
}
}
var option1 = new Option();
// Logs: {key: "foo", value: "bar", autoLoad: true}
var option2 = new Option({value: ''hello''});
// Logs: {key: "foo", value: "hello", autoLoad: true}
Esto es incluso más útil con Typescript, ya que puede garantizar la seguridad del tipo con los valores pasados (es decir, la key
solo podría ser una cadena, autoLoad
un booleano, etc.).
puedes usar métodos estáticos, mira mi respuesta a la misma pregunta
class MyClass {
constructor(a,b,c,d){
this.a = a
this.b = b
this.c = c
this.d = d
}
static BAndCInstance(b,c){
return new MyClass(null,b,c)
}
}
//a Instance that has b and c params
MyClass.BAndCInstance(b,c)