2011-07-07 18 views
15
var name = function(n) { 
    var digits = ['one','two','three','four']; 
    return digits[n]; 
} 

var namenew = (function() { 
    digits = ['one','two','three','four']; 
    return function(n) { 
     return digits[n]; 
    } 
}()); 

दोनों संस्करणों का परिणाम एक ही आउटपुट में होता है, हालांकि ऐसा कहा जाता है कि दूसरा संस्करण पहले संस्करण की तुलना में बहुत तेज है।बंद होने के साथ जावास्क्रिप्ट प्रदर्शन

जैसा कि मैं समझता हूं, पहला संस्करण हर बार फ़ंक्शन निष्पादित करता है जहां दूसरा संस्करण निष्पादन का परिणाम संग्रहीत करता है। यही वह है जो मुझे एक कार्यात्मक/नियमित ओओपीएस प्रोग्रामर के रूप में भ्रमित करता है।

कोई भी अपने आंतरिक संदर्भ के साथ एक फ़ंक्शन कैसे सहेज सकता है? हुड के नीचे क्या हो रहा है? क्या कोई एक स्पष्टीकरण दे सकता है?

+1

यह एक वस्तु है कि अंक सूची शामिल है, के साथ साथ एक विधि बनाने है। –

उत्तर

13

उस प्रश्न का वास्तविक उत्तर लगभग 3 पृष्ठ लंबा होगा। लेकिन मैं इसे जितना संभव हो उतना छोटा बनाने की कोशिश करता हूं। ईसीएमए-/जावास्क्रिप्ट सभी Execution Contexts और Object है। ECMAscript में तीन मूल प्रकार के संदर्भ हैं: Global context, Function contexts और eval contexts

हर बार जब आप कोई फ़ंक्शन कॉल करते हैं, तो आपका इंजन इसे अपने function context में फैलाएगा। इसके अलावा, ऐसे Activation object बनाए गए हैं। इस रहस्यवादी वस्तु एक function context से बाहर होते हैं जो का हिस्सा है कम से कम:

  • [[स्कोप श्रृंखला]]
  • सक्रियण वस्तु
  • "इस" संदर्भ मूल्य

वहाँ अधिक हो सकता है विभिन्न इंजनों पर गुण, लेकिन इन तीनों को ईएस के किसी भी कार्यान्वयन के लिए आवश्यक है। हालांकि, विषय पर वापस। यदि कोई फ़ंक्शन संदर्भ लागू किया जाता है, तो सभी parent contexts (या अधिक सटीक रूप से, Activation objects अभिभावक संदर्भों से) [[Scope]] संपत्ति में कॉपी किए गए हैं। आप इस संपत्ति के बारे में एक सरणी की तरह सोच सकते हैं, जिसमें ऑब्जेक्ट्स (सक्रियण-) ऑब्जेक्ट्स हैं। अब, किसी भी फ़ंक्शन से संबंधित जानकारी सक्रियण ऑब्जेक्ट (औपचारिक पैरामीटर, चर, फ़ंक्शन घोषणाओं) में संग्रहीत होती है।

आपके उदाहरण में, digits चर namenew के लिए सक्रियण ऑब्जेक्ट में संग्रहीत है। दूसरा जब आंतरिक अज्ञात फ़ंक्शन बनाया जाता है, तो यह Activation object को [[Scope]] propertys में जोड़ता है।जब आप digits[n] पर कॉल करते हैं, तो जावास्क्रिप्ट पहले उस चर को अपने में सक्रियण ऑब्जेक्ट में खोजने का प्रयास करता है। यदि यह विफल रहता है, तो खोज स्कोपेचैन में जाती है। और voila, वहां हम चर पाया क्योंकि हम बाहरी समारोह से एओ की प्रतिलिपि बनाई।

मैंने पहले से ही एक संक्षिप्त उत्तर के लिए बहुत कुछ लिखा है, लेकिन वास्तव में इस तरह के एक प्रश्न का अच्छा जवाब देने के लिए आपको यहां ईएस के बारे में कुछ बुनियादी ज्ञान समझाएं। मुझे लगता है कि आपको यह समझने के लिए पर्याप्त है कि वास्तव में "हुड के नीचे" क्या होता है (यदि आप और अधिक पढ़ना चाहते हैं तो मैं कुछ संदर्भ दूंगा)।


आप इसे करने के लिए कहा, तो आप इसे पाने:

http://dmitrysoshnikov.com/ecmascript/javascript-the-core/

8

पहला फ़ंक्शन हर बार निष्पादित होने पर digits पुन: प्रयास करता है। यदि यह एक बड़ी सरणी है तो यह बेहद महंगा है।

दूसरा फ़ंक्शन namenew के साथ साझा किए गए संदर्भ में digits स्टोर करता है। हर बार namenew निष्पादित किया जाता है यह केवल एक ही ऑपरेशन करता है: return digits[n]

इस तरह का एक उदाहरण प्रदर्शन में कोई उल्लेखनीय लाभ नहीं दिखाता है, लेकिन बहुत बड़े सरणी/ऑब्जेक्ट/फ़ंक्शन कॉल प्रदर्शन के साथ महत्वपूर्ण रूप से सुधार किया जाएगा।

एक ओओपी परिप्रेक्ष्य में इस तरीके से बंद करने का उपयोग एक स्थिर चर में डेटा संग्रहीत करने के समान है।


भूल जाते हैं कि namenewपरिणाम बंद समारोह के प्राप्त कर रहा है मत करो। बंद होने पर केवल को पर निष्पादित किया जाता है।

+0

दुर्भाग्यवश, मैंने जो कुछ बताया है, उसे समझता हूं। जो मैं खोज रहा हूं वह है 'हुड के तहत' क्या हो रहा है – Kiran

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