जावास्क्रिप्ट को निजी फंक्शन और स्वयं निष्पादन समारोह के साथ समझना

मैं एंगस क्रॉल जेएस को समझना ब्लॉग पढ़ रहा था और इसे पाया

var a = {
  b: function() {
    var c = function() {
      return this;
    };
    return c();
  }
}; 

a.b();//window

मेरे लिए ऐसा लगता है, सी का आह्वान करने के समय, सी बी के अंदर था। यह आविष्कार संदर्भ होना चाहिए (अगर मैं गलत हूं, तो मुझे सही करें)। जब यह निष्पादित होता है, तो सी() का संदर्भ (यह) खिड़की क्यों है?

there is another example i found in that blog

var a = {
  b: function() {
    return (function() {return this;})();
  }
};

a.b(); //window

बी का संदर्भ खिड़की क्यों है? क्या अनाम कार्य हमेशा वैश्विक संदर्भ में चलता है?

0

2 उत्तर

यह (इच्छित इरादा) को समझने का एक अच्छा तरीका यहां दिया गया है:

फ़ंक्शन के अंदर यह का मान फ़ंक्शन कहलाता है। एक अपवाद के साथ, इसे फ़ंक्शन परिभाषित करने के साथ ऐसा करने की ज़रूरत नहीं है, इसके अंदर अन्य कार्यों को कैसे घोंसला किया जा सकता है, किस वस्तु को परिभाषित किया गया था, किस प्रकार का कार्य है, या इनमें से कोई भी।

जब आप किसी विधि कॉल का उपयोग करके फ़ंक्शन को कॉल करते हैं जैसे foo.bar() या foo [bar]() , यह फ़ंक्शन के अंदर है foo ऑब्जेक्ट।

जब आप एक सामान्य फ़ंक्शन कॉल के साथ फ़ंक्शन को कॉल करते हैं जैसे foo() , यह फ़ंक्शन में विंडो ऑब्जेक्ट है, या यदि फ़ंक्शन उपयोग करता है सख्त मोड यह अपरिभाषित है।

यह एक अपवाद है - यदि फ़ंक्शन स्वयं या उसके आस-पास के कोड में "सख्त उपयोग होता है"; यह सादा फ़ंक्शन कॉल के लिए यह बदलता है। अच्छे कोड के लिए जो कोई फर्क नहीं पड़ता है - आपको कोड लिखना नहीं चाहिए जो कि यह विंडो ऑब्जेक्ट पर निर्भर करता है।

अन्यथा, आप किस चीज की परवाह करते हैं वह है यह एक विधि कॉल में संदर्भित करता है। और यह हमेशा यह निर्धारित करता है कि फ़ंक्शन कहा जाता है , यह कैसे परिभाषित किया गया है।

चलो अपने पहले उदाहरण के माध्यम से चलो।

जब आप a.b() पर कॉल करते हैं, तो आप a ऑब्जेक्ट की विधि के रूप में b को कॉल कर रहे हैं। तो b फ़ंक्शन के अंदर, यह a जैसा ही है।

जैसा कि होता है, यह हमें यह जानने के लिए कोई अच्छा नहीं करता है, क्योंकि b फ़ंक्शन कभी भी यह के साथ कुछ भी नहीं करता है। यह सब एक सामान्य समारोह के रूप में c() को कॉल करता है। तो c के अंदर, यह विंडो ऑब्जेक्ट है, या यदि आप सख्त मोड में थे तो यह अपरिभाषित होगा।

c फ़ंक्शन बस इसके यह मान, या विंडो देता है। और यह b से वापसी मूल्य भी है। इसलिए यही कारण है कि आप परिणाम के रूप में window देखते हैं: यह सब कोड से b और c फ़ंक्शंस को कैसे कॉल करता है।

अब दूसरे उदाहरण के बारे में: ठीक है, यह बहुत ही खराब obfuscated कोड है, है ना? इस कोड को कभी कौन लिखेंगे और किसी को भी पहली नज़र में इसे समझने की उम्मीद है?

तो चलो इसे एक और अधिक पठनीय रूप में बदल दें। यह पंक्ति समस्या है:

    return (function() {return this;})();

आइए कोष्ठक फ़ंक्शन अभिव्यक्ति को बाहर निकालें:

    (function() {return this;})

और इसे एक अस्थायी चर के लिए असाइन करें:

    var temp = (function() {return this;});

हमें अतिरिक्त कोष्ठक की आवश्यकता नहीं है, और चलिए पठनीयता के लिए कोड इंडेंट करें:

    var temp = function() {
        return this;
    };

और हम temp चर को वापसी कथन में फ़ंक्शन के रूप में कॉल कर सकते हैं:

    return temp();

अब हम इसे वापस कोड कोड में b फ़ंक्शन में डाल सकते हैं:

var a = {
  b: function() {
    var temp = function() {
        return this;
    };
    return temp();
  }
};

a.b(); //window

अरे! क्या वह कोड परिचित नहीं दिखता है? वास्तव में, यह temp चर के नाम को छोड़कर पहले उदाहरण के समान है। तो अब आप देखते हैं कि यह पहले के समान क्यों काम करता है।

0
जोड़ा
आपके उत्तर के लिए धन्यवाद। क्या आप थोड़ा और समझाने में सक्षम हो सकते हैं? निजी फ़ंक्शन (फ़ंक्शन के अंदर) जहां मैं बस बना और कॉल करता हूं। वैश्विक संदर्भ तस्वीर में कैसे आते हैं।
जोड़ा लेखक KhanSharp, स्रोत

देखने के लिए एक कुंजी नया कीवर्ड है, जो एक नया संदर्भ स्थापित करता है। नया न देखें? फिर संदर्भ नहीं बदला है, जिसका अर्थ है यह नहीं बदला है। यदि आपने इसे विंडो के भीतर से बुलाया है, तो यह आपका संदर्भ है, और यह आपका यह है। (यदि आप किसी दायरे के साथ कॉल() या लागू() का उपयोग करते हैं, तो यह परिवर्तन करता है, लेकिन यह स्पष्ट रूप से यहां लागू नहीं होता है।)

0
जोड़ा