Wie werden statische Methoden standardmäßig aufgerufen? Ich kann mir vorstellen constructor
, den Namen der Klasse selbst zu verwenden oder zu verwenden. Letzteres gefällt mir nicht, da es sich nicht notwendig anfühlt. Ist der erstere der empfohlene Weg oder gibt es noch etwas anderes?
Hier ist ein (erfundenes) Beispiel:
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
quelle
quelle
SomeObject.print
fühlt sich natürlich an. Aberthis.n
innen macht es keinen Sinn, da es keine Instanz gibt, wenn es um statische Methoden geht.printN
ist jedoch nicht statisch.Antworten:
Beide Methoden sind realisierbar, aber sie bewirken unterschiedliche Dinge, wenn es um die Vererbung mit einer überschriebenen statischen Methode geht. Wählen Sie denjenigen aus, dessen Verhalten Sie erwarten:
Das Verweisen auf die statische Eigenschaft über die Klasse ist tatsächlich statisch und gibt ständig den gleichen Wert an. Wenn Sie
this.constructor
stattdessen verwenden, wird der dynamische Versand verwendet und auf die Klasse der aktuellen Instanz verwiesen, in der die statische Eigenschaft möglicherweise den geerbten Wert hat, aber auch überschrieben werden kann.Dies entspricht dem Verhalten von Python, bei dem Sie entweder über den Klassennamen oder die Instanz auf statische Eigenschaften verweisen können
self
.Wenn Sie erwarten, dass statische Eigenschaften nicht überschrieben werden (und sich immer auf die der aktuellen Klasse beziehen), wie in Java , verwenden Sie die explizite Referenz.
quelle
class
Syntax kennen), es gibt keinen Unterschied in der Definition der Methode. Es geht nur darum, wie Sie es nachschlagen, über die geerbteconstructor
Eigenschaft oder direkt nach ihrem Namen.Property 'staticProperty' does not exist on type 'Function'
Ich stolperte über diesen Thread und suchte nach einer Antwort auf einen ähnlichen Fall. Grundsätzlich sind alle Antworten gefunden, aber es ist immer noch schwierig, das Wesentliche daraus zu extrahieren.
Arten des Zugangs
Angenommen, eine Klasse Foo stammt wahrscheinlich von einer anderen Klasse (n), von der wahrscheinlich mehr Klassen abgeleitet sind.
Dann zugreifen
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);
Hintergrund
this
bezieht sich auf die aktuelle Instanz.super
bezieht sich im Grunde genommen auf dieselbe Instanz, aber etwas Adressierungsmethoden und Getter, die im Kontext einer aktuellen Klasse geschrieben wurden, werden erweitert (unter Verwendung des Prototyps von Foos Prototyp).this.constructor
.this
steht zur Verfügung, um direkt auf die Definition der aktuellen Klasse zu verweisen.super
bezieht sich auch nicht auf eine Instanz, sondern auf statische Methoden und Getter, die im Kontext einer Klasse geschrieben wurden, die derzeit erweitert wird.Fazit
Versuchen Sie diesen Code:
quelle
Own non-overridden instance method/getter / not possible by intention unless using some workaround
--- Das ist wirklich schade. Meiner Meinung nach ist dies ein Mangel von ES6 +. Vielleicht sollte es aktualisiert werden, um einfach darauf zu verweisenmethod
- dhmethod.call(this)
. Besser alsFoo.prototype.method
. Babel / etc. könnte mit einem NFE (benannter Funktionsausdruck) implementiert werden.method.call( this )
ist eine wahrscheinliche Lösung, außer dass diemethod
dann nicht an die gewünschte Basis- "Klasse" gebunden ist und daher keine nicht überschriebene Instanzmethode / Getter ist . Auf diese Weise ist es immer möglich, mit klassenunabhängigen Methoden zu arbeiten. Trotzdem denke ich nicht, dass das aktuelle Design so schlecht ist. Im Kontext von Klassenobjekten, die von Ihrer Basisklasse Foo abgeleitet sind, kann es gute Gründe geben, eine Instanzmethode zu überschreiben. Diese Überschreibungsmethode kann gute Gründe haben, ihresuper
Implementierung aufzurufen oder nicht. Jeder Fall ist förderfähig und sollte befolgt werden. Andernfalls würde es zu einem schlechten OOP-Design führen.arguments.callee
oder eine NFE war.this
), keinen geeigneten Grund sehe . Es klingt wie der Versuch, die Vorteile der Zeigerarithmetik von nacktem C mit höherwertigem C # zu mischen. Nur aus Neugier: Wofür würden Siearguments.callee
sauber gestalteten OOP-Code verwenden?this.inherited(currentFn, arguments);
- wobeicurrentFn
ein Verweis auf die aktuell ausgeführte Funktion ist. Wenn die aktuell ausgeführte Funktion nicht direkt referenziert werden kann, ist sie in TypeScript, das seine Klassensyntax aus ES6 übernimmt, etwas haarig.Wenn Sie irgendeine Art von Vererbung planen, würde ich empfehlen
this.constructor
. Dieses einfache Beispiel sollte veranschaulichen, warum:test1.callPrint()
wird sichConstructorSuper Hello ConstructorSuper!
an der Konsole anmeldentest2.callPrint()
wird sichConstructorSub Hello ConstructorSub!
an der Konsole anmeldenDie benannte Klasse wird die Vererbung nur dann gut behandeln, wenn Sie jede Funktion, die auf die benannte Klasse verweist, explizit neu definieren. Hier ist ein Beispiel:
test3.callPrint()
wird sichNamedSuper Hello NamedSuper!
an der Konsole anmeldentest4.callPrint()
wird sichNamedSuper Hello NamedSub!
an der Konsole anmeldenSehen Sie alle oben genannten in Babel REPL .
Sie können daran erkennen,
test4
dass es immer noch in der Superklasse ist; In diesem Beispiel scheint es keine große Sache zu sein, aber wenn Sie versuchen, überschriebene Elementfunktionen oder neue Elementvariablen zu referenzieren, werden Sie in Schwierigkeiten geraten.quelle