Friday 15 February 2013

JavaScript closure inside loops – simple practical example -


  var funcs = []; के लिए (var i = 0; i & lt; 3; i ++) {// चलो बनाओ 3 फ़ंक्शंस फ़ैंक्स [i] = फ़ंक्शन () {// और उन्हें funcs console.log में संग्रह करें ("मेरा मान:" + i); // प्रत्येक अपने मूल्य लॉग करना चाहिए }; } के लिए (var j = 0; j & lt; 3; j ++) {funcs [j] (); // और अब चलिए हर एक को देखने के लिए चलाते हैं}  

इसे आउटपुट करता है:

मेरा मान : 3
मेरा मान: 3
मेरा मान: 3

जबकि मुझे इसे आउटपुट करना चाहिए:

मेरा मान: 0
मेरा मान: 1
मेरा मान: 2

इस मूल समस्या का समाधान क्या है?

ठीक है, समस्या ये है कि चर i , आपके प्रत्येक बेनामी फ़ंक्शंस के भीतर, फ़ंक्शन के बाहर एक ही चर के लिए बाध्य है।

आप क्या करना चाहते हैं, फ़ंक्शन के बाहर एक अलग, अपरिवर्तनीय मान के लिए प्रत्येक फ़ंक्शन में चर को बाइंड करना है:

  Var funcs = []; फ़ंक्शन createfunc (i) {वापसी फ़ंक्शन () {console.log ("मेरा मान:" + i); }; } के लिए (var i = 0; i & lt; 3; i ++) {funcs [i] = createfunc (i); } के लिए (var j = 0; j & lt; 3; j ++) {funcs [j] (); // और अब चलो हर एक को देखने के लिए चलाते हैं)  

जावास्क्रिप्ट में कोई ब्लॉक का गुंजाइश नहीं है - केवल फ़ंक्शन गुंजाइश - लपेटकर फ़ंक्शन सृजन एक नए फ़ंक्शन में, आप सुनिश्चित करते हैं कि "i" का मान आपके इरादे के रूप में रहता है।


अपडेट: की अपेक्षाकृत व्यापक उपलब्धता के साथ Array.prototype.Each फ़ंक्शन (2015 में), यह ध्यान देने योग्य है कि उन स्थितियों में मुख्यतः मूल्यों की एक सरणी पर चलना शामिल है, .forEach () प्राप्त करने के लिए एक स्वच्छ, प्राकृतिक तरीका प्रदान करता है हर पुनरावृत्ति के लिए एक अलग समापन यह मानते हुए कि आपके पास कुछ प्रकार के सरणी हैं जिसमें मूल्य (डोम संदर्भ, ऑब्जेक्ट्स, जो भी हो), और प्रत्येक तत्व के लिए विशिष्ट कॉलबैक सेट करने की समस्या उत्पन्न होती है, आप यह कर सकते हैं:

  Var someArray = [/ * जो भी * /]; // ... someArray.forEach (फ़ंक्शन (arrayElement) {// ... इस एक तत्व के लिए कोड कोड कोड कुछ एसिंक्रोनस फंक्शन (सरणी एलेमेंट, फ़ंक्शन) {arrayElement.doSomething ();});});  

यह विचार यह है कि .forEach लूप के साथ प्रयोग किए जाने वाले कॉलबैक फ़ंक्शन के प्रत्येक आवागमन का अपना बंद होना होगा। उस हैंडलर में पारित पैरामीटर उस पुनरावर्तन के उस विशेष चरण के लिए विशिष्ट तत्व है। अगर यह एक अतुल्यकालिक कॉलबैक में उपयोग किया जाता है, तो यह पुनरावृत्ति के अन्य चरणों में स्थापित किसी अन्य कॉलबैक से टकराने वाला नहीं होगा।

यदि आप jQuery में काम करना चाहते हैं, तो $। प्रत्येक () फ़ंक्शन आपको एक समान क्षमता देता है।

अपडेट 2: ईसीएमएस्क्रिप्ट 6 (ईएस 6), जावास्क्रिप्ट का नवीनतम संस्करण अब कई लोगों में लागू किया जा रहा है सदाबहार ब्राउज़र और बैकएंड सिस्टम ऐसे भी होते हैं जैसे कि पुराने सिस्टम पर नई सुविधाओं के उपयोग की अनुमति देने के लिए ES6 से ES5 को बदल दिया जाएगा।

ES6 में नया चलो और const कीवर्ड का परिचय दिया गया है को var आधारित चर से भिन्न रूप से स्कॉच किया गया है उदाहरण के लिए, एक चलो आधारित सूचकांक के साथ एक लूप में, लूप के माध्यम से प्रत्येक पुनरावृत्ति का i का नया मान होगा, जहां प्रत्येक मान को पाश के अंदर स्कॉच किया जाता है, इसलिए आपके जैसा कि आप अपेक्षा करते हैं, कोड काम करेगा कई संसाधन हैं, लेकिन मैं सूचना के एक महान स्रोत के रूप में सुझाता हूं।

  के लिए (I = 0; i & lt; 3; i ++) {funcs [i] = फ़ंक्शन () {Console.log ("मेरा मान:" + i); }; }  

सावधान रहें, हालांकि, IE9-IE11 और किनारे से पहले एज 14 समर्थन चलो लेकिन उपरोक्त गलत प्राप्त (वे एक नया <कोड नहीं बनाते हैं > मैं हर बार, इसलिए उपर्युक्त सभी कार्य 3 लॉग होते हैं जैसे वे अगर हम var का इस्तेमाल करते हैं)। एज 14 अंत में यह सही हो जाता है।


No comments:

Post a Comment