2011-01-23 15 views
7

के पाश काउंटर बाध्यकारी मैंने देखा है प्रोग्रामर छोरों अंदर घटनाओं श्रोताओं असाइन करते हैं, काउंटर का उपयोग कर। मेरा मानना ​​है कि इस वाक्य रचना है:कृपया बंद समझाने, या समारोह गुंजाइश

for(var i=0; i < someArray.length; i++){ 
    someArray[i].onclick = (function(i){/* Some code using i */})(i); 
} 

कोई इस के पीछे तर्क समझाने कृपया सकते हैं, और इस अजीब वाक्य रचना, मैं इस कभी नहीं देखा है:

(function(i))(i); 

अपना समय और धैर्य के लिए बहुत धन्यवाद।

+3

इस तकनीकी रूप से बंद होने में शामिल नहीं है। हालांकि मुझे पूरा यकीन नहीं है कि यह कितना अच्छा करता है; वह आंतरिक कार्य तुरंत चलाएगा, और जब तक कि यह कोई अन्य कार्य नहीं करेगा, तो ऑनक्लिक वास्तव में कुछ अजीब पर सेट हो जाएगा। – cHao

+0

@cHao इस तत्काल अज्ञात फ़ंक्शन कॉल के बाद, onlick लिए, यह एक समारोह लौटना चाहिए, ताकि लौटे समारोह के साथ "मैं" पर्यावरण आसपास में चर एक बंद है सौंपते हैं। – jcubic

+0

@jcubic: * कोड वास्तव में एक डोम ईवेंट हैंडलर * स्थापित कर रही है, यह एक समारोह * लौटना चाहिए अगर इसे सही ढंग से काम कर रहा है *। धारणा को औचित्य देने के लिए यहां पर्याप्त कोड नहीं है। – cHao

उत्तर

5

ऐसा इसलिए किया गया है क्योंकि जावास्क्रिप्ट में केवल फ़ंक्शन स्कोप है, ब्लॉक दायरा नहीं है। इसलिए, आपके द्वारा लूप में घोषित प्रत्येक वैरिएबल फ़ंक्शन के दायरे में है और आपके द्वारा बनाए गए प्रत्येक बंद होने पर एक ही चर के लिए उपयोग होता है।

तो एक ही तरीका है एक नया गुंजाइश बनाने के लिए एक समारोह कॉल करने के लिए है और वह है क्या

(function(i){/* Some code using i */}(i)) 

कर रहा है।

ध्यान रखें कि आपके उदाहरण एक महत्वपूर्ण हिस्सा याद करते हैं:

someArray[i].onclick = (function(i){ 
    return function() { 
     /* Some code using i */ 
    } 
}(i)); 

तत्काल समारोह कुछ खास नहीं है: तत्काल समारोह एक और समारोह जो click हैंडलर हो जाएगा वापस जाने के लिए है। यह किसी भी तरह फ़ंक्शन परिभाषा और फ़ंक्शन कॉल को रेखांकित करता है। आप इसे सामान्य फ़ंक्शन कॉल द्वारा प्रतिस्थापित कर सकते हैं:

function getClickHandler(i) { 
    return function() { 
     /* Some code using i */ 
    } 
} 

for(var i=0; i < someArray.length; i++){ 
    someArray[i].onclick = getClickHandler(i); 
} 
+0

धन्यवाद, मुझे मिल गया है :) – Dean

+0

+1 'getClickHandler' संस्करण के लिए +1, जो एक बेहतर दृष्टिकोण आईएमओ है। – user113716

7

(function(i))(i) वाक्य रचना एक गुमनाम समारोह बनाता है और फिर तुरंत निष्पादित करता है।

आमतौर पर आप एक नया समारोह चर के बजाय हर ईवेंट हैंडलर एक ही चर साझा करने की अपनी एक प्रतिलिपि है कि लूप के माध्यम से हर बार, बनाने के लिए यह करूँगा।

उदाहरण के लिए

तो:

for(int i = 0; i < 10; i++) 
    buttons[i].click = function() { doFoo(i); }; 

अक्सर लोगों, बाहर फैल जाती है क्योंकि कोई बात नहीं क्या बटन पर क्लिक करें, doFoo(10) कहा जाता है।

जबकि:

for(int i = 0; i < 10; i++) 
    buttons[i].click = (function(i){ return function() { doFoo(i); };)(i); 

प्रत्येक यात्रा के लिए भीतरी समारोह (i का अपना ही मूल्य के साथ) का एक नया उदाहरण बनाता है और अपेक्षा के अनुरूप काम करता है।

+0

तो तुम समारोह आप गुमनाम समारोह के अंदर विशेष घटना के लिए प्रदान करना चाहते हैं, और उस बिंदु पर "काउंटर" का मान सम्मिलित नए कार्यों दायरे के अंदर रखा जाता है? – Dean

+1

@ डीन: मैंने कुछ जवाब उदाहरण मेरे जवाब में संपादित किए हैं। क्या वे मदद करते हैं? –

+1

@ डीन हां, और यह काम करता है क्योंकि तर्क ** कॉपी किए जाते हैं ** जब वे फ़ंक्शंस (प्राइमेटिव्स के लिए) पास होते हैं। –

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