2015-09-09 16 views
8

पहले से एक ओवरराइड स्थिर विधि कॉलिंग, कुछ कोड मंच तैयार करने के लिए। Child कक्षाओं का प्रारंभिक रूप से वही है, लेकिन प्रत्येक का अपना doImportantStuff() का कार्यान्वयन है, जिसकी वापसी मूल्य इंगित करता है कि क्या विशेष Child तत्काल होना चाहिए।माता पिता

अभी तक इसने मैंने कोशिश की प्रत्येक ट्रांसलेटर में काम किया है, क्योंकि thisParent.init() फ़ंक्शन Child वर्ग के निर्माता को संदर्भित करता है। हालांकि मुझे किसी बच्चे के वर्ग द्वारा ओवरराइड की गई स्थिर विधि का जिक्र करने के बारे में कोई भी दस्तावेज नहीं मिला है, इसलिए सवाल यह है कि क्या मैं हमेशा इस पर भरोसा कर सकता हूं? या, ऐसा करने का कोई और तरीका है?

+6

'इन'' में संदर्भित 'यह' केवल फ़ंक्शन कहलाता है इस पर निर्भर करता है। यदि आप इसे 'Parent.init()' के साथ कहते हैं तो यह 'माता-पिता' को संदर्भित करता है। यदि आप इसे 'Child1.init()' के साथ कहते हैं तो यह 'Child1' को संदर्भित करता है। इसका ईएस 6 के साथ कुछ लेना देना नहीं है, इस प्रकार जावास्क्रिप्ट हमेशा काम करता है (और ES6 उसमें बदलाव नहीं करता है)। –

+0

"विस्तारित खंड" में विस्तार करने के बारे में कुछ है: http://www.2ality.com/2015/02/es6-classes-final.html –

+0

[ईएस 6 - कक्षा के भीतर कॉल स्थैतिक विधि] के संभावित डुप्लिकेट (http://stackoverflow.com/q/31116300/1048572) – Bergi

उत्तर

8

हालांकि मुझे कोई भी दस्तावेज नहीं मिला है, जिसमें एक बच्चे या कक्षा द्वारा ओवरराइड की गई स्थिर विधि का जिक्र करने के बारे में कोई तरीका नहीं है, इसलिए सवाल यह है कि क्या मैं हमेशा इस पर भरोसा कर सकता हूं?

यह मानक फ़ंक्शन-कॉल-थ्रू-ऑब्जेक्ट-प्रॉपर्टी तंत्र है। जब आप ऐसा करेंगे:

Child1.doImportantStuff(); 

... जब तक doImportantStuff एक तीर समारोह (यह नहीं है) या एक बाध्य समारोह (यह नहीं है) है, तो कॉल के दौरान, thisChild1 को तैयार है। बिल्कुल इस तरह:

var obj = { 
    foo: function() { 
     console.log(this === obj); 
    } 
}; 
obj.foo(); // "true" 

तो हाँ, आप उस पर भरोसा कर सकते हैं। (और मैं समझता हूँ कि तुम क्यों पूछा, यह थोड़ा अजीब जब तक आप इसे माध्यम से काम प्रतीत होता है।)

बेशक

, यह एक गैर static समारोह के कोड के भीतर से काम नहीं करेगा, क्योंकि this संदर्भित करेंगे उदाहरण के लिए, कन्स्ट्रक्टर समारोह नहीं। यदि आपको वहां इसकी आवश्यकता है, तो आप this.constructor.doImportantStuff का उपयोग कर सकते हैं जब तक कि किसी ने constructor संपत्ति को गड़बड़ नहीं किया हो। (लोग हमेशा गड़बड़ यह अप करने के लिए इस्तेमाल किया;, यह स्वचालित नई वाक्य रचना के साथ उम्मीद है कि कम नहीं होगा, हालांकि यह दुर्लभ तुम सच में इसकी जरूरत है ...)


सवालों के इन प्रकार के लिए, यह याद रखना महत्वपूर्ण अक्सर उपयोगी है कि नया वर्ग वाक्यविन्यास लगभग पुराने वर्बोज़ तरीके के लिए सिंटैक्टिक चीनी है जो हमने किया (अगर हम वास्तव में पूरी तरह से थे)। यह वास्तव में अच्छा चीनी है, लेकिन यह लगभग सभी है (और यह एक अच्छा बात ™ है)। static विधियों को कन्स्ट्रक्टर फ़ंक्शन के गुणों के रूप में सेट किया गया है, गैर-static विधियों को कन्स्ट्रक्टर की prototype संपत्ति पर ऑब्जेक्ट के गुणों के रूप में सेट किया गया है। (मुझे लगता है कि इसका एकमात्र गैर-चीनी पहलू है, Bergi बताता है कि नया वाक्यविन्यास हमें Array जैसे बिल्टिन का विस्तार करने देता है, जो पहले करना संभव नहीं था। संभव बनाने का एक हिस्सा यह बताता है कि this कैसे मिलता है सेट अप करें [super() से पहले इसे अपने सबक्लास कंस्ट्रक्टर में कॉल नहीं कर सकते], जो new.target से संबंधित है, जो बर्गि discusses here है। ईएस 7 में, यह गोपनीयता सामग्री के साथ चीनी से आगे जा सकता है।)

+0

धन्यवाद! मुझे नहीं पता था कि क्लास सिंटैक्स एक स्थायी तरीके से चीनी था, या दूसरे शब्दों में, मुझे पता था कि यह ट्रांसपेलरों के साथ कैसे काम करता है, लेकिन मुझे यकीन नहीं था कि ब्राउज़र में मूल रूप से कार्यान्वित होने पर यह अभी भी काम करेगा। मुझे डर था कि यह व्यवहार ईएस संस्करण रूपांतरण का सिर्फ एक आर्टिफैक्ट हो सकता है, जो बाद में चलेगा, मेरा कोड तोड़ देगा। यह जानना अच्छा है कि ऐसा नहीं होगा! – Schlaus

+0

हालांकि विरासत चीनी से थोड़ी अधिक है। विशेष रूप से हमारे पास अन्य कन्स्ट्रक्टर फ़ंक्शंस से विरासत में कोई भी रचनात्मक कार्य नहीं था, जो हमें स्थिर विधियों में भी 'सुपर' का उपयोग करने की अनुमति देता है – Bergi

+0

@ बर्गि: लेकिन फिर, यह सिर्फ वाक्य रचनात्मक चीनी है। अगर मेरे पास 'चाइल्ड विस्तारित है', तो 'चाइल्ड' स्थिर विधि में मैं 'super.staticMethod() 'का उपयोग करता हूं, असुरक्षित संस्करण बस' parent.staticMethod()' है। यह सच है कि ईएस 6 में 'चाइल्ड' (उदाहरण के लिए, 'चाइल्ड -> अभिभावक -> फंक्शन.प्रोटोटाइप -> ऑब्जेक्ट.प्रोटोटाइप') की प्रोटोटाइप श्रृंखला में' माता-पिता 'है, लेकिन हम इसे' setPrototypeOf' 'के साथ कर सकते हैं। यह 'वर्ग 'की बजाय' setPrototypeOf' है जो वहां अग्रिम है। मुझे गलत मत समझो, मैं चीनी का बड़ा प्रशंसक हूं, लेकिन अब मुझे लगता है कि यह सब कुछ है, है ना? (यदि आप मुझे यहां पकड़ते हैं तो बहुत आश्चर्यचकित नहीं होंगे।) –

3

आप Parent में

Child1.doImportantStuff(); 

कॉल करने के लिए, बल्कि गतिशील ओवरराइड स्थिर विधि आह्वान नहीं करना चाहते हैं, तो आप कर सकते हैं:

this.constructor.doImportantStuff(); 

यह भी setters के लिए और में काम करता है माता पिता वर्ग के निर्माता:

class Parent { 
 
    static get foo() { 
 
     // Throw an error to indicate that this is an abstract method. 
 
     throw new TypeError('This method should be overridden by inheriting classes.'); 
 
    } 
 

 
    constructor() { 
 
     console.log(this.constructor.foo); 
 
    } 
 

 
    logFoo() { 
 
     console.log(this.constructor.foo); 
 
    } 
 
} 
 

 
class Child extends Parent { 
 
    static get foo() { 
 
     return 'yay'; 
 
    } 
 
} 
 

 
const child = new Child(); // Prints 'yay' 
 
child.logFoo(); // Prints 'yay'

संबंधित मुद्दे