Il semble que dans les classes JavaScript (ES6) super.__proto__ === this.__proto__
.
Pouvez-vous expliquer pourquoi c'est le cas? Le comportement semble cohérent entre les différents navigateurs, donc je soupçonne que cela est spécifié quelque part dans la spécification.
Considérez le code suivant:
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();
Je me serais attendu à ce que super.__proto__.myFunc();
cela appelle la fonction myFunc()
de classe Level1
et cela super.__proto__ !== this.__proto__
. Au lieu de cela, il super.__proto__.myFunc();
appelle en fait la myFunc()
classe Level3
(il s'appelle lui-même), puis lors de la deuxième invocation, il appelle la myFunc()
classe Level2
. Ceci est parfaitement compréhensible si super.__proto__ === this.__proto__
le code le démontre.
Pouvez-vous expliquer la raison pour laquelle super.__proto__ === this.__proto__
dans cet exemple? Si possible, veuillez également fournir des références à la section pertinente de la spécification.
la source
__proto__
fait d'être des fonctions d'accesseurObject.prototype
et de fonctionner sur leurthis
valeur. Mais je ne pouvais tout simplement pas imaginer que celasuper
était réellement spécifié pour fonctionner de cette façon. Je pensaissuper
être à peu près équivalent àthis.__proto__.__proto__
, doncsuper.__proto__
aurait été équivalent àthis.__proto__.__proto__.__proto__
ce qui aurait montré le comportement que j'attendais. Savez-vous où, dans la spécification, le comportement exact desuper
est spécifié?super
, commesuper.setFoo('bar')
. Vous ne voudriez pas que cela fonctionne sur un prototype au lieu de l'instance.__proto__
c'est une propriété d'accesseur surObject.prototype
. Lorsque j'ai demandé une référence à la spécification, je voulais dire une référence au comportement exact dusuper
mot clé en conjonction avec__proto__
. Voir mon commentaire précédent.super.setFoo('bar')
serait, qu'il est équivalent àthis.__proto__.__proto__.setFoo.call(this, 'bar')
. Donc,super
appelle automatiquement les fonctions avec la bonnethis
.super.__proto__
(dans cette méthode de laLevel3
classe) est exactement équivalent àReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)