Es scheint, dass in JavaScript (ES6) Klassen super.__proto__ === this.__proto__
.
Können Sie erklären, warum dies der Fall ist? Das Verhalten scheint in verschiedenen Browsern konsistent zu sein, daher vermute ich, dass dies irgendwo in der Spezifikation angegeben ist.
Betrachten Sie den folgenden Code:
class Level1 {
myFunc() {
console.log('Level1');
}
}
class Level2 extends Level1 {
myFunc() {
console.log('Level2');
}
}
class Level3 extends Level2 {
myFunc() {
console.log('Level3 BEGIN ' + Math.random());
super.__proto__.myFunc();
console.log(super.__proto__ === this.__proto__);
console.log('Level3 END');
}
}
const foo = new Level3();
foo.myFunc();
Ich hätte erwartet, dass super.__proto__.myFunc();
das die Funktion myFunc()
der Klasse nennen würde Level1
und das super.__proto__ !== this.__proto__
. Stattdessen super.__proto__.myFunc();
ruft tatsächlich die myFunc()
Klasse auf Level3
(es ruft sich selbst auf) und beim zweiten Aufruf ruft es die myFunc()
Klasse auf Level2
. Dies ist durchaus verständlich, wenn super.__proto__ === this.__proto__
der Code dies demonstriert.
Können Sie den Grund dafür super.__proto__ === this.__proto__
in diesem Beispiel erklären ? Wenn möglich, geben Sie bitte auch Verweise auf den entsprechenden Abschnitt der Spezifikation an.
quelle
__proto__
dass Accessor-Funktionen tatsächlichObject.prototype
auf ihremthis
Wert arbeiten und daran arbeiten . Aber ich kann mir einfach nicht vorstellen, dass diessuper
tatsächlich so funktioniert. Ich dachtesuper
, ungefähr gleichwertig zu seinthis.__proto__.__proto__
, alsosuper.__proto__
wäre es gleichwertig gewesen,this.__proto__.__proto__.__proto__
was das erwartete Verhalten gezeigt hätte. Wissen Sie, wo in der Spezifikation das genaue Verhalten vonsuper
angegeben ist?super
, wiesuper.setFoo('bar')
. Sie möchten nicht, dass dies auf einem Prototyp anstelle der Instanz ausgeführt wird.__proto__
eine Accessor-Eigenschaft istObject.prototype
. Als ich nach einem Verweis auf die Spezifikation fragte, meinte ich einen Verweis auf das genaue Verhalten dessuper
Schlüsselworts in Verbindung mit__proto__
. Siehe meinen vorherigen Kommentar.super.setFoo('bar')
wäre, dass es gleichbedeutend ist mitthis.__proto__.__proto__.setFoo.call(this, 'bar')
. Ruft alsosuper
automatisch Funktionen mit der richtigen aufthis
.super.__proto__
(in dieser Methode derLevel3
Klasse) ist genau gleichbedeutend mitReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)