2012-02-16 39 views
10

मैं बहुत अजीब कुछ पाया आज के साथ वस्तुओं बनाने:'वापसी' का उपयोग करते हुए जब 'नए'

: यदि आप एक निर्माता समारोह और new कीवर्ड के साथ वस्तुओं बनाते हैं, लेकिन return एक निर्माता से समारोह, यह बहुत तरह बर्ताव करता है
  1. नव निर्मित "ऑब्जेक्ट" इसके बजाय एक फ़ंक्शन है।
  2. नए कार्य को सामान्य की तरह लागू किया जा सकता है कि, हालांकि ...
  3. आप निर्माता समारोह में this के लिए एक संदर्भ बनाए रखते हैं, this संदर्भ एक वस्तु है कि सही ढंग से निर्माता से बनाया गया था। new से आपको वापस आने की उम्मीद है।

    function Constructor() { 
        var self = this; 
    
        this.name = 'instance'; 
        return function() { 
        return self; 
        } 
    } 
    

    तो अगर आप इसे इस तरह instantiated: var instance = new Constructor() निम्नलिखित परिणाम होगा:

    typeof instance //returns "function" 
    typeof instance() //returns "object" 
    instance()   //returns { name: 'instance' } 
    

    तो मुझे लगता है कि मैं तीन प्रश्न हैं:

यहाँ एक उदाहरण है

  1. क्या यह कानूनी है और यह बदतर है के क्रॉस ब्राउज़र? यह वास्तव में कमाल है और मुझे लगता है कि इसका उपयोग कई तरीकों से किया जा सकता है, लेकिन क्या यह व्यवहार भरोसेमंद है?
  2. पृष्ठभूमि में क्या होता है जो इस व्यवहार का कारण बनता है?
  3. (शायद 2 द्वारा उत्तर दिया गया है, लेकिन ...) क्या नया ऑब्जेक्ट (जिसे 'इस' के साथ संदर्भित किया गया है) नए उदाहरण के अंदर है, ताकि यह सब स्वयं निहित हो और कचरा कलेक्टर द्वारा ठीक से साफ किया जा सके?
+0

कन्स्ट्रक्टर से कुछ भी वापस लौटना गलत है, मैंने सुना है। –

उत्तर

7
  1. हाँ, जबकि डिफ़ॉल्ट रूप से एक निर्माता रिटर्न नई वस्तु निर्माण किया जा रहा (जिसके द्वारा this संदर्भित है) तो आप उस वापसी मान जब तक आप एक वस्तु लौट ओवरराइड कर सकते हैं। चूंकि कोई फ़ंक्शन एक ऑब्जेक्ट होता है, इसलिए आप इसे अपने उदाहरण में वापस कर सकते हैं। नव निर्मित वस्तु एक फ़ंक्शन स्वयं ही नहीं है, लेकिन आपका लौटा हुआ कार्य नव निर्मित ऑब्जेक्ट को इसके चरणीय दायरे में संदर्भित करता है।

  2. देखें # 1

  3. इसका कारण यह है एक समारोह, एक बंद बनाता है तो यह संदर्भ के लिए self चर, जो संदर्भ के लिए वास्तविक वस्तु निर्माण किया जा रहा होता है जारी है। इसलिए मैं यह नहीं कहूंगा कि यह "अंदर" कुछ भी है, बल्कि यह कार्य के परिवर्तनीय दायरे का हिस्सा है।

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

function Constructor() { 

    this.name = 'instance'; 
    return [ this ]; // Instead return an Array that references the new object 
} 
+0

मैं देखता हूं! तो मेरे उदाहरण में परिवर्तनीय "उदाहरण" एक * बंद * है, सामान्य कार्य नहीं है? और उस बंद में दोनों लौटे हुए फ़ंक्शन और तत्काल ऑब्जेक्ट होते हैं, जिन्हें "इस" से एक्सेस किया जा सकता है? –

+2

@ केविनएमसीटीग: ठीक है, सभी कार्य बंद हैं। यह जावास्क्रिप्ट में कार्यों के आंतरिक कार्यान्वयन का हिस्सा है। फ़ंक्शन को बंद करने का क्या कारण है कि इसका मूल वैरिएबल स्कोप का स्थायी संदर्भ है जहां इसे बनाया गया था। तो आप बस एक सादा पुराना फ़ंक्शन लौट रहे हैं, जो कि किसी भी अन्य फ़ंक्शन की तरह ठीक से व्यवहार कर रहा है, जिसमें यह इसके चरम दायरे को नहीं देखता है * (जिसमें 'स्वयं' चर शामिल है, जो आपकी नई वस्तु का संदर्भ देता है) *। –

2

अच्छा, यह वास्तव में एक अच्छा सवाल है और जैसा कि आपने अनुमान लगाया होगा, आसानी से उत्तर नहीं दिया गया है।

इसे बहुत आसान रखने के लिए:
1) हाँ और हाँ; यह उन अद्भुत सुविधाओं में से एक है जिन्हें आप "पारंपरिक" प्रोग्रामिंग भाषाओं में नहीं ढूंढते हैं।
2) कृपया के बारे में बंद (नीचे लिंक)
3) हाँ (कृपया अधिक पढ़ सकते हैं)

आपको Javascript क्लोजर के बारे में अधिक पढ़ना चाहिए पढ़ें: http://jibbering.com/faq/notes/closures/
http://www.javascriptkit.com/javatutors/closures.shtml (यहां आप कुछ अच्छा काम कर उदाहरण मिल गया)

और, विशेष रूप से, परजीवी विरासत मॉडल:
http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/

मुझे आशा है कि इस मदद करता है

+0

लिंक के लिए धन्यवाद। दूसरा एक बहुत दिलचस्प है। मैंने आज एक नया शब्द सीखा है: पावर कन्स्ट्रक्टर –

1
इस

आप क्या कहते हैं एक closure

क्या यह करता है एक आत्म निहित कोड (आमतौर पर एक वस्तु के रूप में जाना जाता है) पर्यावरण

typeof instance //returns "function" - since it's not "fired" or called. just returns the function declaration (correct me if i'm wrong) 
typeof instance() //returns "object" - it returns an object since you called it 
instance()   //returns an object also - you called it, but you didn't store it 

एक वस्तु का एक उदाहरण बनाने के है का उपयोग कर बनाया है एक बंद:

function Constructor() { 
    var privateProperty = 'private'; 
    var privateMethod = function(){ 
     alert('called from public method'); 
    }; 

    //return only what's to be seen in public 
    return { 
     publicProperty: 'im public', 
     publicMethod: function(){ 
      alert('called from public method'); 
     } 
     getter: privateMethod //assign to call the private method 
    } 
} 

var myObj = Constructor(); 
var pubProp = myObj.publicProperty; // pubProp = 'im public' 
myObj.publicMethod()    //alert: 'called from public method'; 
myObj.getter()      //alert: 'called from public method'; 

//cannot access since "private": 
myObj.privateProperty 
myObj.privateMethod 
+1

_ "यह क्या करता है एक स्वयं निहित कोड वातावरण (आमतौर पर एक वस्तु के रूप में जाना जाता है)" _ - आम तौर पर "बंद" के रूप में जाना जाता है। यह एक "ऑब्जेक्ट" नहीं है, कम से कम एक जेएस ऑब्जेक्ट होने के अर्थ में नहीं। साथ ही, यदि आपका कार्य स्पष्ट रूप से किसी ऑब्जेक्ट को लौटाता है तो इसे 'नया' के साथ कॉल करने का एक अच्छा अभ्यास नहीं है क्योंकि यह भ्रामक है - यदि 'नया' का उपयोग करते हुए आप परिणाम को 'निर्माता' का उदाहरण मानेंगे। – nnnnnn

+0

बंद होने पर एमडीएन पृष्ठ के मुताबिक: * "एक बंद एक विशेष प्रकार की वस्तु है जो दो चीजों को जोड़ती है: एक समारोह, और पर्यावरण जिसमें वह कार्य बनाया गया था।" * –

+1

@nnnnnn मैंने बस सरल शब्दों में समझाया। हालांकि यह anobject नहीं है, यह एक वस्तु (निजी और सार्वजनिक गुण होने) अनुकरण करने के लिए इसका उपयोग आम है। 'नए' के ​​लिए .. मुझे इसके बारे में पता नहीं था। – Joseph

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