Neden JavaScript'te (super .__ proto__ === this .__ proto__) doğrudur?


10

Görünüşe göre JavaScript (ES6) Sınıflarında super.__proto__ === this.__proto__.

Neden böyle olduğunu açıklayabilir misiniz? Davranış farklı tarayıcılarda tutarlı görünüyor, bu yüzden bu özellikte bir yerde belirtildiğinden şüpheleniyorum.

Aşağıdaki kodu göz önünde bulundurun:

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();

Bunu umuyordum super.__proto__.myFunc();işlevini çağırır myFunc()sınıfın Level1ve o super.__proto__ !== this.__proto__. Bunun yerine super.__proto__.myFunc();aslında myFunc()sınıf Level3çağrıları (kendini çağırır) ve daha sonra ikinci çağrıda myFunc()sınıf çağrısı yapar Level2. Bu, super.__proto__ === this.__proto__kodun gösterdiği durumlarda mükemmel bir şekilde anlaşılabilir .

super.__proto__ === this.__proto__Bu örnekte nedenini açıklayabilir misiniz ? Mümkünse, lütfen spesifikasyonun ilgili bölümüne de referans verin.

Yanıtlar:


6

Object.prototype.__proto__alıcısı olan bir mülktür [1] . thisDeğeri üzerinde çalışır . Hiçbir gerçek yoktur superbir olmaya nesne thisdeğeri (yazma yapamadı Object.getPrototypeOf(super)), sadece superbu yüzden, özelliklerini bakmanın yolu this.__proto__ve super.__proto__uzun olduğu kadar aynı anlama __proto__da her yerde alt prototip zincirinde tanımlanmadı.

Karşılaştırmak:

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__'));


Ben zaten bunun __proto__aslında erişimci fonksiyonları üzerinde Object.prototypeve thisdeğer üzerinde çalışan olmak ile ilgili bir şey olduğundan şüphelendim . Ama bunun superaslında bu şekilde çalıştığını belirlediğimi düşünmüyorum . superKabaca eşdeğer olduğunu düşündüm this.__proto__.__proto__, bu yüzden beklediğim davranışı sergileyen super.__proto__eşdeğer this.__proto__.__proto__.__proto__olurdu. Spesifikasyonda tam davranışının nerede belirtildiğini biliyor musunuz super?
Jens Moser

@JensMoser: birazdan bulmak, ancak normal kullanımları hayal edeceğiz supergibi super.setFoo('bar'). Bunun örnek yerine bir prototip üzerinde çalışmasını istemezsiniz.
Ry-

@georg Bunun __proto__bir erişimci özelliği olduğunu biliyorum Object.prototype. Spesifikasyona bir referans istediğimde, superanahtar kelimenin tam davranışıyla birlikte bir referans demek istedim __proto__. Önceki yorumuma bakın.
Jens Moser

@ Ry- Evet, biraz basitleştirdim. Benim tam olarak benim anlayışım super.setFoo('bar'), eşdeğer olması this.__proto__.__proto__.setFoo.call(this, 'bar'). Böylece, superotomatik olarak doğru ile fonksiyonları çağırır this.
Jens Moser

1
@JensMoser super.__proto__( Level3sınıfın bu yönteminde ) tam olarak eşdeğerReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)
Bergi
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.