क्यों जावास्क्रिप्ट में है (सुपर .__ proto__ === यह .__ proto__) सच है?


10

ऐसा लगता है कि जावास्क्रिप्ट (ईएस 6) कक्षाओं में super.__proto__ === this.__proto__

क्या आप बता सकते हैं कि ऐसा क्यों है? व्यवहार अलग-अलग ब्राउज़रों में सुसंगत लगता है, इसलिए मुझे संदेह है कि यह कल्पना में कहीं निर्दिष्ट है।

निम्नलिखित कोड पर विचार करें:

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

मैं उम्मीद है कि super.__proto__.myFunc();समारोह कहेंगे myFunc()वर्ग की Level1और कहा कि super.__proto__ !== this.__proto__। इसके बजाय super.__proto__.myFunc();वास्तव myFunc()में वर्ग की कॉल Level3(यह खुद को कहता है) और फिर दूसरे आह्वान पर इसे myFunc()कक्षा का कॉल कहता है Level2। यह पूरी तरह से समझ में आता है अगर super.__proto__ === this.__proto__कोड प्रदर्शित करता है।

क्या आप super.__proto__ === this.__proto__इस उदाहरण में इसका कारण बता सकते हैं ? यदि संभव हो, तो कृपया संबंधित अनुभाग के संदर्भ भी प्रदान करें।

जवाबों:


6

Object.prototype.__proto__एक प्रापक के साथ एक संपत्ति है [1] । यह इसके thisमूल्य पर संचालित होता है । मूल्य superहोने के लिए कोई वास्तविक वस्तु नहीं है this(आप लिख नहीं सकते Object.getPrototypeOf(super)), बस superगुणों को देखने का एक तरीका है, this.__proto__और super.__proto__इसका मतलब वही है जब तक __proto__कि प्रोटोटाइप श्रृंखला पर कहीं भी कम परिभाषित नहीं किया जाता है।

की तुलना करें:

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


मुझे पहले से ही संदेह था कि इससे __proto__वास्तव में एक्सेसरी फ़ंक्शंस होने Object.prototypeऔर उनके thisमूल्य पर काम करने के लिए कुछ करना था । लेकिन मैंने अभी कल्पना नहीं की superथी कि वास्तव में इस तरह से काम करने के लिए निर्दिष्ट किया गया था। मैंने superलगभग this.__proto__.__proto__उसी के समतुल्य होने के बारे में सोचा था , इसलिए मेरे super.__proto__समकक्ष वह this.__proto__.__proto__.__proto__व्यवहार प्रदर्शित होगा जिसकी मुझे अपेक्षा थी। क्या आप जानते हैं, कल्पना में सटीक व्यवहार superकहाँ निर्दिष्ट किया गया है?
जेन्स मोजर

@JensMoser: मैं इसे थोड़ा सा ढूँढूँगा, लेकिन superजैसे सामान्य उपयोग की कल्पना करता हूँ super.setFoo('bar')। आप उदाहरण के बजाय एक प्रोटोटाइप पर काम नहीं करना चाहते हैं।
Ry-

@georg मुझे पता है कि __proto__एक एक्सेसर प्रॉपर्टी है Object.prototype। जब मैंने कल्पना के संदर्भ के लिए पूछा, तो मेरा मतलब था कि superसंयोजन के साथ कीवर्ड के सटीक व्यवहार का संदर्भ __proto__। मेरी पिछली टिप्पणी देखें।
जेन्स मोजर

@ राय- हां, मैंने थोड़ा सरल किया। मेरी सटीक समझ super.setFoo('bar')यह होगी कि यह इसके बराबर है this.__proto__.__proto__.setFoo.call(this, 'bar')। तो, superस्वचालित रूप से सही के साथ कार्यों को आमंत्रित करता है this
जेन्स मोजर

1
@JensMoser super.__proto__( Level3कक्षा के उस तरीके में ) बिल्कुल विपरीत हैReflect.get(Object.getPrototypeOf(Level3.prototype), "__proto__", this)
Bergi
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.