Tampaknya dalam Kelas JavaScript (ES6) super.__proto__ === this.__proto__
.
Bisakah Anda jelaskan mengapa ini masalahnya? Perilaku ini tampaknya konsisten di berbagai browser, jadi saya curiga ini ditentukan di suatu tempat dalam spesifikasi.
Pertimbangkan kode berikut:
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();
Saya akan berharap itu super.__proto__.myFunc();
akan memanggil fungsi myFunc()
kelas Level1
dan itu super.__proto__ !== this.__proto__
. Sebaliknya super.__proto__.myFunc();
sebenarnya panggilan myFunc()
kelas Level3
(panggilan itu sendiri) dan kemudian pada doa kedua panggilan myFunc()
kelas Level2
. Ini sangat bisa dipahami jika super.__proto__ === this.__proto__
kode menunjukkan.
Bisakah Anda menjelaskan alasannya mengapa super.__proto__ === this.__proto__
dalam contoh ini? Jika memungkinkan, berikan juga referensi ke bagian spesifikasi yang relevan.
sumber
__proto__
benar-benar menjadi fungsi pengaksesObject.prototype
dan beroperasi padathis
nilai mereka . Tapi saya tidak bisa membayangkansuper
itu sebenarnya ditentukan untuk bekerja dengan cara ini. Saya pikirsuper
kira-kira setara denganthis.__proto__.__proto__
, jadisuper.__proto__
akan sama denganthis.__proto__.__proto__.__proto__
yang akan menunjukkan perilaku yang saya harapkan. Apakah Anda tahu, di mana dalam spesifikasi perilaku yang tepatsuper
ditentukan?super
, sepertisuper.setFoo('bar')
. Anda tidak ingin itu beroperasi pada prototipe alih-alih instance.__proto__
ini adalah properti accessorObject.prototype
. Ketika saya meminta referensi ke spec, saya berarti referensi untuk perilaku yang tepat darisuper
kata kunci dalam hubungannya dengan__proto__
. Lihat komentar saya sebelumnya.super.setFoo('bar')
akan, bahwa itu setara denganthis.__proto__.__proto__.setFoo.call(this, 'bar')
. Jadi,super
secara otomatis memanggil fungsi dengan benarthis
.super.__proto__
(dalam metodeLevel3
kelas) persis sama denganReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)