2013-02-13 9 views
7

अगर मैं Chrome डेवलपर टूल के भीतर इस कोड चलाएँ:डिबगिंग मॉड्यूल पैटर्न को प्रकट करना: कॉल किए जाने तक कार्यक्षेत्र में कार्य नहीं करता है?

var test = (function() { 

    var publicFunction, 
     privateFunction1, 
     privateFunction2; 

    privateFunction1 = function privateFunction1() { 
    return true; 
    }; 

    privateFunction2 = function privateFunction2() { 
    return true; 
    }; 

    publicFunction = function publicFunction() { 
    privateFunction1(); 
    debugger; 
    }; 

    return { 
    publicFunction: publicFunction 
    }; 
})(); 

क्यों ब्रेकप्वाइंट पर दायरे में privateFunction1 है, जबकि privateFunction2 नहीं है?

Screenshot of Chrome Dev Tools

+1

साइड नोट: आपके द्वारा घोषित किए गए चर द्वारा कोई उद्देश्य नहीं दिया गया है, आप इसके बजाय ऐसा कर सकते हैं (और शायद चाहिए): http://pastie.org/6150861 क्योंकि आप * नामित फ़ंक्शन एक्सप्रेशन * असाइन कर रहे हैं उन चर, IE8 पर और नीचे आप अपने प्रत्येक कार्य के लिए दो कार्य बना रहे हैं (दो अलग-अलग समय पर)। एक अंतर जो तब तक कोई फर्क नहीं पड़ता जब तक कि आप दोनों में से किसी एक का उपयोग करके किसी ईवेंट हैंडलर को हुक अप नहीं करते हैं और बाद में इसे दूसरे के साथ अनचेक करने का प्रयास करते हैं। मेरे ब्लॉग पर अधिक: [* डबल-टेक *] (http://blog.niftysnippets.org/2010/09/double-take.html) –

+1

अच्छा, मैंने * सोचा * ऐसा इसलिए था क्योंकि वी 8 (क्रोम का जावास्क्रिप्ट इंजन) था 'privateFunction2' को पूरी तरह से हटा रहा है क्योंकि इसे कहीं भी उपयोग नहीं किया गया था (यह मृत कोड था)। फिर मैंने इसे कहीं और इस्तेमाल करके साबित करने की कोशिश की, और इससे कुछ भी नहीं बदला। बहुत, बहुत अजीब। –

+0

धन्यवाद, मुझे एनएफई के साथ आईईएस मुद्दों के बारे में पता नहीं था। फिर भी, मैं घोषणाओं पर नामित फ़ंक्शन एक्सप्रेशन पसंद करता हूं, अगर केवल इसलिए कि मैं hoisting से नापसंद करता हूं। – janfoeh

उत्तर

4

दिलचस्प सवाल है।

privateFunction2publicFunction के लिए दायरे में है, लेकिन publicFunction वास्तव में यह कभी नहीं का उपयोग करता है। मुझे विश्वास है कि आप डीबगर में क्या देख रहे हैं क्योंकि वी 8 (क्रोम का जावास्क्रिप्ट इंजन) विभिन्न कारणों (स्मृति उपयोग को कम करने सहित) के बंद होने की सामग्री को अनुकूलित करता है।

सिद्धांत रूप में, विनिर्देश के अनुसार, publicFunction उस क्षेत्र में सभी प्रतीकों को बंद कर देता है (इसका एक स्थायी संदर्भ है) जहां यह परिभाषित किया गया है। विशेष रूप से, execution context आपके बाहरी अज्ञात फ़ंक्शन पर कॉल के लिए बनाया गया था, और निष्पादन संदर्भ में lexical environment संबंधित binding object के साथ publicFunction में एक अंतर्निहित, अज्ञात संदर्भ है। उस बाध्यकारी वस्तु के गुण (सिद्धांत में) नाम publicFunction, privateFunction1, privateFunction2, और कुछ अन्य चीजें (arguments और ऐसे) के साथ गुण हैं।

लेकिन बात publicFunction वास्तव में कुछ भी संदर्भ नहीं है कि लेकिन privateFunction1 है, और इसके लिए जगह में कोड के साथ, यह नहीं संदर्भ कुछ और कर सकते हैं। इसके लिए किसी और चीज का संदर्भ देने के लिए, आपको अपना कोड बदलना होगा, और निश्चित रूप से वे V8 एक अलग निर्णय लेगा। publicFunction में कोड eval(string) या new Function(string) कॉल नहीं है, इसलिए V8 संदर्भों के प्रतीकों पर एक स्थिर विश्लेषण करने के लिए स्वतंत्र है। इसका मतलब है कि, डीबगर अनुपस्थित है, बाध्यकारी वस्तु को उन अन्य गुणों को रखने के लिए कोई भी बिंदु नहीं है। उनका कभी भी उपयोग नहीं किया जाता है।

चूंकि वी 8 आक्रामक अनुकूलक कंपाइलर (हाँ, कंपाइलर) है, जाहिर है कि यह निष्पादन संदर्भ की बाध्यकारी वस्तु से मृत गुणों को हटा देता है।

यदि मैं publicFunction पर कुछ जोड़ता हूं जो privateFunction2 का उपयोग किसी भी चीज़ के लिए करता है, तो मैं इसे कंसोल से देख सकता हूं जैसे कि मैं privateFunction1 कर सकता हूं।

+0

ऐसा लगता है कि आप सही हैं: अगर मैं सार्वजनिक कार्य को पैरामीटर देता हूं और इसे eval करता हूं, तो बाकी सब कुछ अपेक्षित रूप में दिखाई देता है। धन्यवाद! – janfoeh

+0

@janfoeh: खुशी हुई है कि मदद की! –

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