¿Cuál es la forma estándar de llamar a métodos estáticos? Puedo pensar en usar constructor
o usar el nombre de la clase en sí, no me gusta este último ya que no me parece necesario. ¿Es la primera la forma recomendada o hay algo más?
Aquí hay un ejemplo (artificial):
class SomeObject {
constructor(n){
this.n = n;
}
static print(n){
console.log(n);
}
printN(){
this.constructor.print(this.n);
}
}
javascript
class
static
ecmascript-6
es6-class
simonzack
fuente
fuente
SomeObject.print
se siente natural Pero porthis.n
dentro no tiene sentido ya que no hay instancia, si estamos hablando de métodos estáticos.printN
embargo, @dfsq no es estático.Respuestas:
Ambas formas son viables, pero hacen cosas diferentes cuando se trata de herencia con un método estático anulado. Elija el comportamiento que espera:
Hacer referencia a la propiedad estática a través de la clase será realmente estática y constantemente dará el mismo valor. En su
this.constructor
lugar, usará el despacho dinámico y se referirá a la clase de la instancia actual, donde la propiedad estática podría tener el valor heredado pero también podría anularse.Esto coincide con el comportamiento de Python, donde puede elegir hacer referencia a propiedades estáticas, ya sea a través del nombre de la clase o la instancia
self
.Si espera que las propiedades estáticas no se anulen (y siempre se refieren a la de la clase actual), como en Java , use la referencia explícita.
fuente
class
sintaxis), no hay diferencia en la definición del método. Es solo una cuestión de cómo buscarlo, a través de laconstructor
propiedad heredada o directamente por su nombre.Property 'staticProperty' does not exist on type 'Function'
Me topé con este hilo en busca de una respuesta a un caso similar. Básicamente se encuentran todas las respuestas, pero aún es difícil extraer lo esencial de ellas.
Tipos de acceso
Suponga que una clase Foo probablemente deriva de alguna otra clase (s) con probablemente más clases derivadas de ella.
Luego accediendo
this.method()
this.property
Foo.method()
Foo.property
this.constructor.method()
this.constructor.property
this.method()
this.property
Foo.method()
Foo.property
Foo.prototype.method.call( this )
Object.getOwnPropertyDescriptor( Foo.prototype,"property" ).get.call(this);
Antecedentes
this
se refiere a la instancia actual.super
Básicamente se refiere a la misma instancia, pero de alguna manera se está ampliando los métodos y captadores escritos en el contexto de alguna clase actual (mediante el uso del prototipo del prototipo de Foo).this.constructor
.this
está disponible para referirse directamente a la definición de clase actual.super
tampoco se refiere a alguna instancia, sino a métodos estáticos y captadores escritos en el contexto de alguna clase actual que se está extendiendo.Conclusión
Prueba este código:
fuente
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- Es una verdadera pena. En mi opinión, esta es una deficiencia de ES6 +. Tal vez debería actualizarse para permitir simplemente referirse amethod
, es decirmethod.call(this)
. Mejor queFoo.prototype.method
. Babel / etc. podría implementarse usando una NFE (expresión de función con nombre).method.call( this )
es una solución probable, excepto quemethod
no está vinculada a la "clase" base deseada en ese momento y, por lo tanto, no puede ser un método / getter de instancia no anulado . Siempre es posible trabajar con métodos independientes de la clase de esa manera. Sin embargo, no creo que el diseño actual sea tan malo. En el contexto de los objetos de clase derivados de su clase base Foo, puede haber buenas razones para anular un método de instancia. Ese método anulado puede tener buenas razones para invocar susuper
implementación o no. Cualquiera de los casos es elegible y debe ser obedecido. De lo contrario, terminaría en un mal diseño de OOP.arguments.callee
una NFE.this
). Suena como tratar de mezclar los beneficios de la aritmética de puntero de C desnuda con C # de nivel superior. Solo por curiosidad: ¿para quéarguments.callee
usarías en un código OOP de diseño limpio?this.inherited(currentFn, arguments);
- dondecurrentFn
hay una referencia a la función que se está ejecutando actualmente. No poder hacer referencia directa a la función que se está ejecutando actualmente es un poco difícil en TypeScript, que toma su sintaxis de clase de ES6.Si está planeando hacer algún tipo de herencia, entonces lo recomendaría
this.constructor
. Este simple ejemplo debería ilustrar por qué:test1.callPrint()
iniciará sesiónConstructorSuper Hello ConstructorSuper!
en la consolatest2.callPrint()
iniciará sesiónConstructorSub Hello ConstructorSub!
en la consolaLa clase nombrada no se ocupará muy bien de la herencia a menos que redefina explícitamente cada función que haga referencia a la Clase nombrada. Aquí hay un ejemplo:
test3.callPrint()
iniciará sesiónNamedSuper Hello NamedSuper!
en la consolatest4.callPrint()
iniciará sesiónNamedSuper Hello NamedSub!
en la consolaVer todo lo anterior en ejecución en Babel REPL .
Puedes ver en esto que
test4
todavía piensa que está en la superclase; en este ejemplo, puede no parecer un gran problema, pero si está tratando de hacer referencia a funciones de miembros que han sido anuladas o nuevas variables de miembros, se encontrará en problemas.fuente