Quelle est la manière standard d'appeler des méthodes statiques? Je peux penser à utiliser constructor
ou utiliser le nom de la classe elle-même, je n'aime pas ce dernier car cela ne me semble pas nécessaire. La première méthode est-elle recommandée ou y a-t-il autre chose?
Voici un exemple (artificiel):
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
la source
la source
SomeObject.print
semble naturel. Mais à l'this.n
intérieur n'a aucun sens puisqu'il n'y a pas d'instance, si nous parlons de méthodes statiques.printN
n'est cependant pas statique.Réponses:
Les deux méthodes sont viables, mais elles font des choses différentes lorsqu'il s'agit d'héritage avec une méthode statique remplacée. Choisissez celui dont vous attendez le comportement:
Faire référence à la propriété static via la classe sera en fait statique et donnera constamment la même valeur. Utiliser à la
this.constructor
place utilisera la répartition dynamique et fera référence à la classe de l'instance actuelle, où la propriété statique peut avoir la valeur héritée mais peut également être remplacée.Cela correspond au comportement de Python, où vous pouvez choisir de faire référence à des propriétés statiques via le nom de la classe ou l'instance
self
.Si vous vous attendez à ce que les propriétés statiques ne soient pas remplacées (et faites toujours référence à celle de la classe actuelle), comme en Java , utilisez la référence explicite.
la source
class
syntaxe), il n'y a aucune différence dans la définition de la méthode. C'est juste une question de savoir comment vous le recherchez, via laconstructor
propriété héritée ou directement par son nom.Property 'staticProperty' does not exist on type 'Function'
Je suis tombé sur ce fil à la recherche d'une réponse à un cas similaire. En gros, toutes les réponses sont trouvées, mais il est encore difficile d'en extraire l'essentiel.
Types d'accès
Supposons qu'une classe Foo soit probablement dérivée d'une ou plusieurs autres classes avec probablement plus de classes dérivées.
Puis accéder
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);
Contexte
this
fait référence à l'instance actuelle.super
fait essentiellement référence à la même instance, mais un peu les méthodes d'adressage et les getters écrits dans le contexte d'une classe actuelle s'étend (en utilisant le prototype du prototype de Foo).this.constructor
.this
est disponible pour se référer directement à la définition de la classe courante.super
ne fait pas non plus référence à une instance, mais à des méthodes statiques et des getters écrits dans le contexte d'une classe actuelle.Conclusion
Essayez ce code:
la source
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- C'est vraiment dommage. À mon avis, c'est une lacune de ES6 +. Peut-être qu'il devrait être mis à jour pour permettre simplement de faire référence àmethod
- c'est- à -diremethod.call(this)
. Mieux queFoo.prototype.method
. Babel / etc. pourrait implémenter en utilisant une NFE (expression de fonction nommée).method.call( this )
est une solution probable sauf que lemethod
n'est pas lié à la «classe» de base souhaitée et ne peut donc pas être une méthode / getter d'instance non surchargée . Il est toujours possible de travailler avec des méthodes indépendantes de la classe de cette façon. Néanmoins, je ne pense pas que la conception actuelle soit si mauvaise. Dans le contexte des objets de classe dérivés de votre classe de base Foo, il peut y avoir de bonnes raisons de remplacer une méthode d'instance. Cette méthode surchargée peut avoir de bonnes raisons d'invoquersuper
ou non son implémentation. Les deux cas sont éligibles et doivent être respectés. Sinon, cela se terminerait par une mauvaise conception de la POO.arguments.callee
ou un NFE.this
). Cela ressemble à essayer de mélanger les avantages de l'arithmétique des pointeurs de C nu avec C # de plus haut niveau. Juste par curiosité: à quoi utiliseriez-vousarguments.callee
dans un code POO proprement conçu?this.inherited(currentFn, arguments);
- oùcurrentFn
est une référence à la fonction en cours d'exécution. Ne pas pouvoir référencer directement la fonction en cours d'exécution la rend un peu poilue dans TypeScript, qui tire sa syntaxe de classe d'ES6.Si vous prévoyez de faire n'importe quel type d'héritage, je vous le recommande
this.constructor
. Cet exemple simple devrait illustrer pourquoi:test1.callPrint()
se connecteraConstructorSuper Hello ConstructorSuper!
à la consoletest2.callPrint()
se connecteraConstructorSub Hello ConstructorSub!
à la consoleLa classe nommée ne traitera pas correctement l'héritage à moins que vous ne redéfinissiez explicitement chaque fonction qui fait une référence à la classe nommée. Voici un exemple:
test3.callPrint()
se connecteraNamedSuper Hello NamedSuper!
à la consoletest4.callPrint()
se connecteraNamedSuper Hello NamedSub!
à la consoleVoir tout ce qui précède en cours d'exécution dans Babel REPL .
Vous pouvez voir de cela qui
test4
pense toujours que c'est dans la super classe; dans cet exemple, cela peut ne pas sembler un gros problème, mais si vous essayez de référencer des fonctions membres qui ont été remplacées ou de nouvelles variables membres, vous vous retrouverez en difficulté.la source