2012-08-23 14 views
9

मैं यह समझने की कोशिश कर रहा हूं कि आंतरिक फ़ंक्शन को बाहरी फ़ंक्शन की सार्वजनिक संपत्ति तक क्यों पहुंचा जा सकता है जब बाहरी फ़ंक्शन को सीधे कॉल किया जाता है, लेकिन जब इसे किसी को असाइन नहीं किया जाता है चर?फ़ंक्शन को कॉल करने और फ़ंक्शन का उदाहरण बनाने के बीच जावास्क्रिप्ट अंतर

उदाहरण:

function outer(x,y){ 

    this.x = x; 
    this.y = y; 

    function inner(){ 
     alert(this.x);  
    } 

    inner(); 
} 

outer(1,2); //As expected, alerts 1 
var func = outer(1,2) //Also alert 1 
var func2 = new outer(1,2); //Alerts undefined 

एक बात मैं करने की कोशिश की alert(this.x); से this कीवर्ड निकालने के लिए था और यह तीनों मामलों के लिए काम किया है। हालांकि, अगर मैं this कीवर्ड हटा देता हूं, तो मैं पारित पैरामीटर तक पहुंच सकता हूं, न कि सार्वजनिक चर, जो निश्चित रूप से वांछित कार्रवाई नहीं है। क्या कोई इस व्यवहार को समझा सकता है?

+0

Ony उपयोग 'this' समारोह शरीर के अंदर है, अगर आप चाहते हैं' new' के माध्यम से यह आह्वान करने के लिए, या एक विधि के रूप में, या के माध्यम से '.call में से एक()' मूल रूप से क्या लिखा है/'.apply()' /'.bind() 'विधियां। एक फ़ंक्शन जिसे 'funcName()' के माध्यम से नियमित रूप से बुलाया जाता है, उसे 'this' का उपयोग नहीं करना चाहिए। –

+1

इसके अलावा, यदि जावास्क्रिप्ट प्रोग्राम सख्त मोड में चलता है, और 'funcName()' के माध्यम से एक फ़ंक्शन का आह्वान किया जाता है, तो 'यह' अपरिभाषित 'होगा। नतीजतन, संपत्ति का उपयोग (उदा। 'This.x') एक संदर्भ त्रुटि फेंकता है। –

उत्तर

12

जब आप outer(1, 2) ऐसा कहते हैं, thiswindow के लिए एक संदर्भ है, तो "x" और "y" प्रभावी रूप से वैश्विक चर रहे हैं। यही कारण है कि inner() "x" तक पहुंच सकता है।

जब आप new outer(1, 2) पर कॉल करते हैं तो आपने this ("बाहरी" में) को एक नई वस्तु का संदर्भ देने के लिए कारण बनाया है। जब "बाहरी" के अंदर "आंतरिक" कहा जाता है, this अभी भी window का संदर्भ देगा, इसलिए कोई "x" नहीं है।

this का मान प्रत्येक फ़ंक्शन कॉल के लिए निर्धारित किया गया है, और मान केवल उस कॉल के विवरण पर निर्भर करता है। इस प्रकार तथ्य यह है कि आप new के माध्यम से "बाहरी" को कॉल करते हैं, इंटीरियर कॉल पर "आंतरिक" — पर कोई प्रभाव नहीं पड़ता है क्योंकि आप केवल inner(); के रूप में फ़ंक्शन को कॉल करते हैं, उस फ़ंक्शन के अंदर this का मान window (ठीक है, वैश्विक संदर्भ, जो कुछ भी है)।

यहां कुछ ऐसे तरीके this एक समारोह के लिए एक कॉल पर सेट किया जा सकता है: समारोह new ऑपरेटर के माध्यम से कहा जाता है

  1. , तो this एक नव निर्मित वस्तु के पास भेजेगा।
  2. यदि किसी ऑब्जेक्ट (foo.someFunction()) पर किसी प्रॉपर्टी लुकअप के माध्यम से फ़ंक्शन का संदर्भ प्राप्त होता है, तो this उस ऑब्जेक्ट का संदर्भ होगा।
  3. यदि फ़ंक्शन प्रोटोटाइप से .call() या .apply() के माध्यम से फ़ंक्शन को कॉल किया जाता है, तो this उन कार्यों का उपयोग करने वाले पहले तर्क को संदर्भित करेगा, यदि आवश्यक हो तो ऑब्जेक्ट वैल्यू पर ले जाया गया है।
  4. यदि फ़ंक्शन को एक साधारण "नग्न" संदर्भ के माध्यम से बुलाया जाता है, तो this वैश्विक संदर्भ (ब्राउज़र में window) का संदर्भ देगा। संपादित करें — Šime Vidas सख्ती से ऊपर एक टिप्पणी में बताता है कि इस मामले में thisnull (जो वास्तव में थोड़ा अधिक समझ में आता है, और ओपी में देखी गई अजीबता से बच जाएगा)।
+1

विंडो में इशारा करते हुए आंतरिक फ़ंक्शन के अंदर 'यह' क्यों है? – Asciiom

+0

@ जेरोमेनमून क्योंकि आंतरिक रूप से कॉल इस तरह से किया जाता है कि इसके लिए और कुछ भी नहीं है। – Pointy

+0

ठीक है तो यह 'किसी भी अन्य चर से भिन्न व्यवहार करता है? मेरा मतलब है, अगर आप बाहरी कार्य के अंदर एक var परिभाषित करेंगे (लेकिन अंदर के फ़ंक्शन के बाहर;)), और इसे अंदर के फ़ंक्शन के अंदर उपयोग किया जाता है, तो यह सही होगा? – Asciiom

5

वहाँ जावास्क्रिप्ट में एक समारोह पड़ता कि इनमें से प्रत्येक को बदलने क्या this की सामग्री है उपयोग करने के लिए 4 तरीके हैं:

  • फ़ंक्शन को कॉल: इस वैश्विक वस्तु = (ब्राउज़र में विंडो)
  • विधि कॉल: यह = ऑब्जेक्ट इसे से कॉल किया जाता है।
  • कन्स्ट्रक्टर कॉल: यह = नया ऑब्जेक्ट जो आप बना रहे हैं।
  • कॉल/लागू कॉल: यह = ऑब्जेक्ट जो आपने पारित किया था।

अपने मामले this == window में जब आप सीधे (outer()) फ़ंक्शन को कॉल करें, लेकिन अगर आप का उपयोग कर फोन नई (new outer()) तो यह नई वस्तु आप बना रहे हैं हो जाएगा।

मैं here

+0

हा हा हां मैंने उस अन्य उत्तर से आपकी "परिदृश्यों की सूची" स्पष्टीकरण चुरा लिया :-) – Pointy

+0

जब तक लोग उनसे सीखते हैं मुझे कोई फर्क नहीं पड़ता ;-) –

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