Parece que en JavaScript (ES6) Clases super.__proto__ === this.__proto__
.
¿Puedes explicar por qué este es el caso? El comportamiento parece consistente en diferentes navegadores, por lo que sospecho que esto se especifica en algún lugar de la especificación.
Considere el siguiente código:
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();
Hubiera esperado que eso super.__proto__.myFunc();
llamara la función myFunc()
de clase Level1
y eso super.__proto__ !== this.__proto__
. En cambio, en super.__proto__.myFunc();
realidad llama myFunc()
a la clase Level3
(se llama a sí mismo) y luego, en la segunda invocación, llama myFunc()
a la clase Level2
. Esto es perfectamente comprensible si super.__proto__ === this.__proto__
el código lo demuestra.
¿Puedes explicar la razón por qué super.__proto__ === this.__proto__
en este ejemplo? Si es posible, proporcione también referencias a la sección relevante de la especificación.
fuente
__proto__
estar realmente en funciones de accesoObject.prototype
y operar en suthis
valor. Pero no podía imaginar que ensuper
realidad se especificara que funcionara de esta manera. Pensé ensuper
ser más o menos equivalente athis.__proto__.__proto__
, porsuper.__proto__
lo que habría sido equivalente athis.__proto__.__proto__.__proto__
lo que habría exhibido el comportamiento que esperaba. ¿Sabes en qué parte de la especificación se especifica el comportamiento exacto desuper
?super
, comosuper.setFoo('bar')
. No querrás que opere en un prototipo en lugar de la instancia.__proto__
es una propiedad de acceso enObject.prototype
. Cuando solicité una referencia a la especificación, quise decir una referencia al comportamiento exacto de lasuper
palabra clave en conjunto con__proto__
. Ver mi comentario anterior.super.setFoo('bar')
sería, que es equivalente athis.__proto__.__proto__.setFoo.call(this, 'bar')
. Entonces,super
invoca automáticamente las funciones con el correctothis
.super.__proto__
(en ese método de laLevel3
clase) es exactamente equivalente aReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)