2012-08-16 13 views
5

ठीक है, मुझे नहीं पता कि इस प्रश्न के लिए शीर्षक को कैसे वाक्यांशित किया जाए।क्लोजर स्कोप कैद नहीं किया गया? - कॉफ़ीस्क्रिप्ट

openDir = (path) -> 
socket.emit "get_metadata", path, (data) -> 
    columnBox = $ "<div/>", class: "columnbox" 
    for item in data.contents 
     itemBox = $ "<div/>", class: "itembox" 
     itemBox.click -> 
      columnBox_inner.children().removeClass "selected" 
      itemBox.addClass "selected" # <<<--- Over here 
      openDir item.path 
     columnBox.append itemBox 
    columnBox.appendTo "#columnscontainer" 

मैं समझता हूँ कि चर itemBoxopenDir के दायरे में यहाँ परिभाषित किया गया है। लेकिन चूंकि इंगित लाइन एक लैम्ब्डा फ़ंक्शन में है, तो itemBox नहीं होना चाहिए, इसके बाद संदर्भित अंतिम ऑब्जेक्ट में उत्परिवर्तित होने के बजाय मूल दायरे के itemBox द्वारा संदर्भित ऑब्जेक्ट को कैप्चर करें?

इसे स्पष्ट रूप से रखने के लिए, मैं प्रत्येक के क्लिक हैंडलर को addClass "selected" निष्पादित करने की अपेक्षा करता हूं। लेकिन क्या होता है कि प्रत्येक क्लिक हैंडलर में itemBox हमेशा अंतिम आइटम बॉक्स का संदर्भ लेता है।

मैं आइटमबॉक्स को घोषित कहां बदलकर इसे आसानी से ठीक कर सकता हूं। अर्थात

data.contents.forEach (item) -> 

में

for item in data.contents 

बदल रहा लेकिन मैं जानना चाहता है कि लैम्ब्डा समारोह चर वर्तमान मूल्य पर कब्जा नहीं करता चाहते हैं।

+0

प्रश्न 'openDir item.path' लाइन में संदर्भित' आइटम' चर पर भी लागू होता है, यहां तक ​​कि 'ओपनडियर' के दायरे में भी परिभाषित किया जाता है। –

उत्तर

9

इस पाश: | स्क्रिप्ट गुंजाइश

for item in data.contents 
    itemBox = $ "<div/>", class: "itembox" 

कुछ हद तक भ्रामक अगर आप (जावा कॉफी) के लिए इस्तेमाल नहीं कर रहे हैं। scoping वास्तव में अधिक इस तरह दिखता है:

itemBox = undefined 
for item in data.contents 
    itemBox = $ "<div/>", class: "itembox" 

तो वहाँ केवल एक ही itemBox चर और है कि एक ही चर लूप के प्रत्येक पुनरावृत्ति द्वारा इस्तेमाल किया जाता है। क्लिक हैंडलर itemBox का संदर्भ रखता है लेकिन क्लिक हैंडलर को तब तक चर का मूल्यांकन नहीं करता है, इसलिए सभी हैंडलर उसी itemBox मान के साथ समाप्त होते हैं और यह लूप के अंत में itemBox मान होगा।

fine manual से

:

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

तो तुम ऐसा कर सकता है:

for item in data.contents 
    do (item) -> 
     # As before... 

अपने itemBox व्यक्तिगत रूप से पाश के प्रत्येक यात्रा के दायरे वाला मिलता है।

forEach का उपयोग करना:

data.contents.forEach (item) -> 
एक सरल पाश के बजाय

काम करता है क्योंकि आप प्रभावी रूप से पाश के शरीर के रूप में एक समारोह का उपयोग कर रहे हैं और उस समारोह के अंदर कोई भी चर कि समारोह के दायरे वाला हो जाएगा।

+0

मुझे दायरे के हिस्से के बारे में पता था। लेकिन आपने जो उल्लेख किया है, 'क्लिक हैंडलर' itemBox' का संदर्भ रखता है लेकिन ** वैरिएबल का मूल्यांकन नहीं करता है जब तक क्लिक हैंडलर को ** 'कहा जाता है, जो मुझे नहीं पता था। मैंने माना था कि चर के द्वारा इंगित ऑब्जेक्ट का संदर्भ क्लिक हैंडलर द्वारा रखा गया था। धन्यवाद! –