Wygląda na to, że w klasach JavaScript (ES6) super.__proto__ === this.__proto__
.
Czy możesz wyjaśnić, dlaczego tak jest? Zachowanie wydaje się spójne w różnych przeglądarkach, więc podejrzewam, że jest to określone gdzieś w specyfikacji.
Rozważ następujący kod:
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();
Spodziewałbym się, super.__proto__.myFunc();
że nazwałoby to funkcję myFunc()
klasy Level1
i to super.__proto__ !== this.__proto__
. Zamiast tego super.__proto__.myFunc();
faktycznie wywołuje myFunc()
klasę Level3
(sama się nazywa), a następnie przy drugim wywołaniu wywołuje myFunc()
klasę Level2
. Jest to całkowicie zrozumiałe, jeśli super.__proto__ === this.__proto__
pokazuje to kod.
Czy możesz wyjaśnić powód, dla którego super.__proto__ === this.__proto__
w tym przykładzie? Jeśli to możliwe, proszę również podać odniesienia do odpowiedniej sekcji specyfikacji.
źródło
__proto__
funkcje akcesora działająObject.prototype
i działają na ichthis
wartości. Ale po prostu nie mogę sobie wyobrazić, żesuper
tak naprawdę działało w ten sposób. Myślałem, że będęsuper
mniej więcej równorzędnythis.__proto__.__proto__
, więcsuper.__proto__
byłby równoważny zthis.__proto__.__proto__.__proto__
tym, co pokazałoby zachowanie, którego się spodziewałem. Czy wiesz, gdzie w specyfikacjisuper
podano dokładne zachowanie ?super
, takie jaksuper.setFoo('bar')
. Nie chciałbyś, aby działał na prototypie zamiast instancji.__proto__
jest to właściwość akcesoriumObject.prototype
. Kiedy poprosiłem o odniesienie do specyfikacji, miałem na myśli odniesienie do dokładnego zachowaniasuper
słowa kluczowego w połączeniu z__proto__
. Zobacz mój poprzedni komentarz.super.setFoo('bar')
, że jest to równoważnethis.__proto__.__proto__.setFoo.call(this, 'bar')
. Tak więcsuper
automatycznie wywołuje funkcje z poprawnymthis
.super.__proto__
(w tej metodzieLevel3
klasy) jest dokładnie równoważnyReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)