2010-04-02 17 views
112

यहाँ मैं चलाने के लिए कोशिश कर रहा हूँ कुछ का एक सरलीकृत संस्करण है:मैं किसी जेएस वैरिएबल के मान (संदर्भ नहीं) को फ़ंक्शन में कैसे पास करूं?

for (var i = 0; i < results.length; i++) { 
    marker = results[i]; 
    google.maps.event.addListener(marker, 'click', function() { 
     change_selection(i); 
    }); 
} 

लेकिन मुझे लगता है कि हर श्रोता results.length का मूल्य (मूल्य जब पाश के लिए समाप्त हो जाता है) का उपयोग करता है खोजने हूँ। मैं श्रोताओं को कैसे जोड़ सकता हूं कि जब मैं इसे संदर्भित करता हूं, तो मैं प्रत्येक के मूल्य का उपयोग करता हूं, इसके संदर्भ में?

उत्तर

158

आप एक समारोह पैरामीटर के रूप में यह पारित करके एक अलग गुंजाइश है कि अपनी वर्तमान स्थिति में चर की बचत होती है बनाने की जरूरत:

for (var i = 0; i < results.length; i++) { 
    (function (i) { 
    marker = results[i]; 
    google.maps.event.addListener(marker, 'click', function() { 
     change_selection(i); 
    }); 
    })(i); 
} 

एक गुमनाम समारोह बनाने और पहले तर्क के रूप में चर के साथ यह फोन कर करके, आप फ़ंक्शन में गुजरने और बंद करने के लिए मूल्य-दर-मूल्य कर रहे हैं।

+3

आप वैश्विक नामस्थान को प्रदूषित न करने के लिए 'मार्कर' से पहले 'var' जोड़ना चाहते हैं। – ThiefMaster

+2

@ थिफमास्टर: आश्चर्यजनक रूप से पर्याप्त, मैंने थोड़ी देर में पहली बार इस उत्तर को देखने के बाद एक ही चीज़ सोचा। हालांकि, ओपी के कोड को देखते हुए, हम पूरी तरह से यह सुनिश्चित नहीं कर सकते कि 'मार्कर' पहले से ही वैश्विक चर नहीं है। –

+0

ने Google के मानचित्र API का उपयोग किया है, हम सुरक्षित रूप से शर्त लगा सकते हैं कि मार्कर का दायरा लूप के बाहर है। अच्छा पकड़ एंडी। –

2

आप बंद होने के साथ आगे बढ़ रहे हैं। Here's an article on closures और उनके साथ कैसे काम करें। पृष्ठ पर उदाहरण 5 देखें; वह परिदृश्य है जिसके साथ आप काम कर रहे हैं।

संपादित करें: चार साल बाद, वह लिंक मर चुका है। उपरोक्त मुद्दे की जड़ यह है कि for लूप रूप बंद हो जाता है (विशेष रूप से marker = results[i] पर)। addEventListener में पारित किया गया है, तो आप बंद होने का साइड इफेक्ट देखते हैं: अंतिम "पुनरावृत्ति" को अंतिम पुनरावृत्ति के बाद बंद होने के माध्यम से अंततः "सहेजा गया" से पहले लूप के प्रत्येक पुनरावृत्ति के साथ अद्यतन किया जाता है। MDN explains this very well.

12

बंद:

for (var i = 0, l= results.length; i < l; i++) { 
    marker = results[i]; 
    (function(index){ 
     google.maps.event.addListener(marker, 'click', function() { 
      change_selection(index); 
     }); 
    })(i); 
} 

संपादित करें 2013: ये अब आमतौर पर एक IIFE

+0

कुछ भी नहीं * गलत * यहां, लेकिन -1 क्योंकि सिर्फ एंडी ई पहले स्पष्टीकरण के साथ मिला; यह उत्तर पेज पर कुछ भी नहीं जोड़ता है क्योंकि यह खड़ा है। –

+3

मुझे यकीन नहीं है कि आप डाउनवॉटिंग के कारणों को समझते हैं। और यह उत्तर एंडी (उत्कृष्ट) उत्तर के अलावा जानकारी जोड़ता है: IIFE। –

35

साथ ही बंद रूप में भेजा जाता है, तो आप function.bind उपयोग कर सकते हैं:

google.maps.event.addListener(marker, 'click', change_selection.bind(null, i)); 

i का मान पास करता है I जब बुलाया समारोह के लिए एक तर्क के रूप में n। (null बाध्यकारी this है, जो आपको इस मामले में की जरूरत नहीं है के लिए है।)

function.bind प्रोटोटाइप रूपरेखा के द्वारा शुरू की गई थी और ECMAScript पांचवें संस्करण में मानकीकृत किया गया है। इस समय तक ब्राउज़रों सब यह मूल रूप से समर्थन करते हैं, आप अपने खुद के function.bind समर्थन का उपयोग कर बंद जोड़ सकते हैं:

if (!('bind' in Function.prototype)) { 
    Function.prototype.bind= function(owner) { 
     var that= this; 
     var args= Array.prototype.slice.call(arguments, 1); 
     return function() { 
      return that.apply(owner, 
       args.length===0? arguments : arguments.length===0? args : 
       args.concat(Array.prototype.slice.call(arguments, 0)) 
      ); 
     }; 
    }; 
} 
+2

बस यह देखा, +1। मैं 'बाइंड' का काफी प्रशंसक हूं और मूल कार्यान्वयन के लिए इंतजार नहीं कर सकता। –

+0

कौन से ब्राउज़र इसका समर्थन करते हैं? कोई मोबाइल ब्राउज़र? – NoBugs

+2

@ नोबग्स: वर्तमान में: आईई 9 +। Fx4 +, हाल ही में क्रोम और ओपेरा संस्करण। सफारी नहीं, आईफोन नहीं, एंड्रॉइड ब्राउज़र में आइसक्रीम सैंडविच के बाद से यह है। – bobince

-4

मुझे लगता है हम मैं के मूल्य को स्टोर करने के लिए एक अस्थायी चर परिभाषित कर सकते हैं।

for (var i = 0; i < results.length; i++) { 
var marker = results[i]; 
var j = i; 
google.maps.event.addListener(marker, 'click', function() { 
    change_selection(j); 
}); 
} 

हालांकि मैंने इसका परीक्षण नहीं किया है।

+4

नहीं, यह काम नहीं करता – newacct

+5

कारण यह काम नहीं करेगा कि जावास्क्रिप्ट में ब्लॉक-स्तरीय स्कोपिंग की कमी है। सभी स्कोपिंग कार्य-स्तर है। आप फ़ंक्शन को कॉल करके केवल एक नया दायरा बना सकते हैं, जो हम अन्य उत्तरों में देखते हैं। लूप के प्रत्येक पुनरावृत्ति के लिए एक फ़ंक्शन को कॉल किए बिना, प्रत्येक मानचित्र-ईवेंट-श्रोता कॉलबैक को अलग-अलग बंद करने का कोई तरीका नहीं है। यह एक समस्या है जो आपके लिए पारदर्शी रूप से सुलझाई जाती है जब भी आप '$ .each() 'या' _.each() 'जैसे पुनरावृत्ति-सहायक का उपयोग करते हैं। – Keen

-2
for (var i = 0; i < results.length; i++) { 
    marker = results[i]; 
    google.maps.event.addListener(marker, 'click', (function(i) { 
     return function(){ 
      change_selection(i); 
     } 
    })(i)); 
} 
+7

यह एक बेहतर जवाब होगा यदि आपने समझाया कि यह क्यों काम करता है। –

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

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