It seems that in JavaScript (ES6) Classes super.__proto__ === this.__proto__
.
Can you explain why this is the case? The behaviour seems consistent across different browsers, so I suspect this is specified somewhere in the spec.
Consider the following 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();
I would have expected that super.__proto__.myFunc();
would call the function myFunc()
of class Level1
and that super.__proto__ !== this.__proto__
. Instead super.__proto__.myFunc();
actually calls myFunc()
of class Level3
(it calls itself) and then on the second invocation it calls myFunc()
of class Level2
. This is perfectly comprehensible if super.__proto__ === this.__proto__
which the code demonstrates.
Can you explain the reason why super.__proto__ === this.__proto__
in this example? If possible, please also provide references to the relevant section of the spec.
Object.prototype.__proto__
is a property with a getter[1]. It operates on its this
value. There is no actual super
object to be a this
value (you couldn’t write Object.getPrototypeOf(super)
), just a super
way of looking up properties, so this.__proto__
and super.__proto__
mean the same thing as long as __proto__
isn’t also defined anywhere lower on the prototype chain.
Compare:
class Parent {
get notProto() {
return this instanceof Child;
}
}
class Child extends Parent {
test() {
console.log(super.notProto);
}
}
new Child().test();
// bonus: [1]
console.log(Object.getOwnPropertyDescriptor(Object.prototype, '__proto__'));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With