मैं एक रैपर तंत्र बनाना चाहता हूं: हम c को लपेटते हैं, इसलिए नई नई वस्तु w के अपने गुण और विधियां हैं लेकिन c भी पहुंच योग्य हैं।

// Note: this class might be from an external lib
class C {
  f() {
    console.log('f (original)');
    this.p = 'p';
  }
}

class W {
  f() {
    console.log('f (new)');
    super.f();  // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}

// Note: this value is external for us
const c = new C();

const w = Object.create(null, Object.getOwnPropertyDescriptors(W.prototype));
Object.setPrototypeOf(w, c);

w.f();  // expected:
        // f (new)
        // f (original)
        // p

क्या मैं इसे सही तरीके से करता हूँ?

त्रुटि क्यों होती है?

अपडेट करें: पी.एस. मैं समझता हूं कि मैं रचना का उपयोग कर सकता हूं लेकिन मैं त्रुटि के स्रोत को समझना चाहता हूं।

0
Kuraga 3 अक्टूबर 2018, 17:02

2 जवाब

सबसे बढ़िया उत्तर

त्रुटि क्यों होती है?

क्योंकि W.prototype.f विधि जो super का उपयोग करती है, केवल W.prototype के प्रोटोटाइप की परवाह करती है ताकि यह मूल्यांकन किया जा सके कि super क्या संदर्भित करेगा। super कीवर्ड अनिवार्य रूप से एक स्थिर लुकअप है, जो उस ऑब्जेक्ट पर निर्भर करता है जिसमें विधि घोषित की गई थी, उस ऑब्जेक्ट की प्रोटोटाइप श्रृंखला को अनदेखा करते हुए जिस पर विधि को बुलाया गया था।

अगर हम इसका अनुवाद करते हैं

class W {
  f() {
    console.log('f (new)');
    Object.getPrototypeOf(W.prototype).f.call(this); // TypeError: (intermediate value).f is not a function
    console.log(this.p);
  }
}

हम देख सकते हैं कि Object.prototype.f एक फलन नहीं है...


तो आप Object.setPrototypeOf(w, c) (या w = Object.create(c, …)) के बजाय Object.setPrototypeOf(W.prototype, C.prototype) करके समस्या को ठीक कर सकते हैं, लेकिन मैं इसकी अनुशंसा नहीं कर सकता। यदि आप वास्तव में सभी उदाहरणों को प्रभावित करना चाहते हैं, तो आपने पहले ही class W extends C लिखा होगा (जिसका परिणाम Object.setPrototypeOf(W.prototype, C.prototype) का उपयोग करने के समान होगा)।

1
Bergi 3 अक्टूबर 2018, 17:24

उदाहरण के लिए आप extends कीवर्ड का उपयोग करना चाहते हैं:

    class C {
        f() { console.log( "C.f" ); }
    }

    class W extends C {
        f() {
            super.f()
            console.log( "W.f" );
        }
    }

    const w = new W();
    w.f(); // will output C.f W.f
0
Ben Randle 3 अक्टूबर 2018, 15:28