2009-01-13 9 views
254

मैं जावास्क्रिप्ट और YUI दोनों के लिए नया हूं। YUI पुस्तकालय उदाहरण के लिए, आप इस संरचना के कई उपयोग पा सकते हैं:किसी ऑब्जेक्ट/फ़ंक्शन/क्लास घोषणा के आस-पास कोष्ठक का अर्थ क्या है?

(function() { 
    var Dom = YAHOO.util.Dom, 
    Event = YAHOO.util.Event, 
    layout = null, 
     ... 
})(); 

मुझे लगता है कि कोष्ठकों पिछले कुछ सिर्फ घोषणा के बाद समारोह निष्पादित करने के लिए कर रहे हैं।

... लेकिन फ़ंक्शन घोषणा के आस-पास के पिछले सेट के बारे में क्या है?

मुझे लगता है कि यह दायरा का मामला है; यह बाहरी कार्यों और संभावित रूप से वैश्विक वस्तुओं के अंदर चर के अंदर छिपाने के लिए है। क्या यह? अधिक आम तौर पर, उन कोष्ठक के यांत्रिकी क्या हैं?

+9

मुझे लगता है कि हमें डुप्लिकेट दोनों की आवश्यकता है, क्योंकि उन्हें इतना अलग कहा गया है। –

+0

यह हटाने का एक अच्छा कारण नहीं है, लेकिन मुझे नहीं पता कि हम डुप्लिकेट के रूप में क्यों नहीं बंद कर सकते हैं। –

+1

इस पर भी चर्चा की गई है [फ़ंक्शन() {})() के बीच अंतर; और फ़ंक्शन() {}();] (http://stackoverflow.com/questions/423228/difference-between-function-and- कार्यक्षमता)। –

उत्तर

3

पहला ब्रांड्स, यदि आप करेंगे, तो संचालन का आदेश होगा। फ़ंक्शन परिभाषा के आस-पास कोष्ठक के सेट का 'परिणाम' फ़ंक्शन स्वयं ही है, जो वास्तव में, कोष्ठक का दूसरा सेट निष्पादित करता है।

यह क्यों उपयोगी है, मैं किसी भी विचार के लिए जावास्क्रिप्ट विज़ार्ड के लिए पर्याप्त नहीं हूं। : पी

192

यह एक स्व-निष्पादित अनाम कार्य है। कोष्ठक के पहले सेट में अभिव्यक्तियों को निष्पादित किया जाना चाहिए, और कोष्ठक का दूसरा सेट उन अभिव्यक्तियों को निष्पादित करता है।

पैरेंट नेमस्पेस से चर छुपाने का प्रयास करते समय यह एक उपयोगी निर्माण है। फ़ंक्शन के भीतर सभी कोड फ़ंक्शन के निजी दायरे में निहित हैं, जिसका अर्थ यह है कि इसे फ़ंक्शन के बाहर से एक्सेस नहीं किया जा सकता है, जिससे यह वास्तव में निजी हो जाता है।

देखें:

http://en.wikipedia.org/wiki/Closure_%28computer_science%29

http://peter.michaux.ca/articles/javascript-namespacing

+35

कोष्ठक केवल इस संदर्भ में आवश्यक है क्योंकि संदर्भ के आधार पर जावास्क्रिप्ट में 'function' एक कथन या अभिव्यक्ति दोनों हो सकता है। कोष्ठक इसे अभिव्यक्ति के रूप में मजबूर करता है। निम्नलिखित भी मान्य है: 'var x = function() {return 1}() 'भले ही कोई आस-पास के कंस्ट्रैसिस न हों। बस एक अभिव्यक्ति की अभिव्यक्ति की अभिव्यक्ति और अनुप्रयोग '(...)'। एक मामले में, मैं उद्घाटन कोष्ठक से पहले ';' डालने की अनुशंसा करता हूं: मैं अर्द्ध-कोलन मुक्त कोड लिखता हूं और ''' से शुरू होने वाली रेखाओं को पिछली पंक्ति से जारी अभिव्यक्ति के रूप में पार्स किया जा सकता है। –

+0

@ user166390 => अंत में "()" अंत में क्यों डालें "}" – Alexander

129

एंडी ह्यूम काफी gave जवाब है, मैं तो बस कुछ और विवरण जोड़ना चाहते हैं।

इस निर्माण के साथ आप अपने मूल्यांकन वातावरण या बंद होने के साथ एक अनाम कार्य बना रहे हैं, और फिर आप इसका तुरंत मूल्यांकन करते हैं। इसके बारे में अच्छी बात यह है कि आप अज्ञात फ़ंक्शन से पहले घोषित चरों तक पहुंच सकते हैं, और आप स्थानीय चर का उपयोग इस फ़ंक्शन के अंदर किसी मौजूदा चर को गलती से ओवरराइट किए बिना कर सकते हैं।

वर कीवर्ड का उपयोग बहुत महत्वपूर्ण है, क्योंकि जावास्क्रिप्ट में हर चर डिफ़ॉल्ट रूप से वैश्विक है, लेकिन कीवर्ड के साथ आप एक नया, lexically scoped चर बनाने, कि है, यह कोड से दिखाई दे रहा है दो ब्रेसिज़ के बीच। आपके उदाहरण में, आप अनिवार्य रूप से वाईयूआई पुस्तकालय में वस्तुओं के लिए लघु उपनाम बना रहे हैं, लेकिन इसमें अधिक शक्तिशाली उपयोग हैं।

मैं एक कोड उदाहरण के बिना आप छोड़ने के लिए नहीं करना चाहते, इसलिए मैं यहाँ एक सरल उदाहरण एक बंद वर्णन करने के लिए डाल देता हूँ:

var add_gen = function(n) { 
    return function(x) { 
    return n + x; 
    }; 
}; 
var add2 = add_gen(2); 
add2(3); // result is 5 

यहाँ क्या चल रहा है? फ़ंक्शन add_gen आप एक और फ़ंक्शन बना रहे हैं जो इसके तर्क के लिए n नंबर जोड़ देगा।चाल यह है कि फंक्शन पैरामीटर सूची में परिभाषित चर में अक्षरों को स्केल किए गए चर के रूप में कार्य करते हैं, जैसे var के साथ परिभाषित किए गए।

लौटे समारोह ब्रेसिज़add_gen समारोह के बीच परिभाषित किया गया है तो यह की n मूल्य के बाद भी add_gen समारोह का निष्पादन पूरा होने के लिए उपयोग होगा, वह यह है कि जब क्रियान्वित कारण है कि आप 5 मिल जाएगा उदाहरण की आखिरी पंक्ति।

फ़ंक्शन पैरामीटर की मदद से

lexically scoped जा रहा है, आप के चारों ओर "समस्याओं" गुमनाम कार्यों में पाश वैरिएबल का उपयोग से उत्पन्न होने वाले काम कर सकते हैं। एक साधारण उदाहरण लें:

for(var i=0; i<5; i++) { 
    setTimeout(function(){alert(i)}, 10); 
} 

"उम्मीद" परिणाम शून्य से चार नंबर हो सकता है, लेकिन आप के बजाय फाइव्स के चार उदाहरणों मिलता है। यह इसलिए होता है क्योंकि setTimeout में अज्ञात फ़ंक्शन और पाश के लिए बहुत ही प्रयोग कर रहे हैंमैं चर, और समय के कार्यों का मूल्यांकन करने के लिए, मैं हो जाएगा 5.

आप मिल भोलेपन से उम्मीद कर सकते हैं आपके प्रश्न और तथ्य में तकनीक का उपयोग करके परिणाम, कि फ़ंक्शन पैरामीटर शब्दावली से स्कॉप्ड हैं। (मैं एक other answer में इस दृष्टिकोण का उपयोग किया है)

for(var i=0; i<5; i++) { 
    setTimeout(
    (function(j) { 
     return function(){alert(j)}; 
    })(i), 10); 
} 

बाहरी समारोह के तत्काल मूल्यांकन आप एक पूरी तरह से स्वतंत्र प्रत्येक चरण में जे नामित चर बना रहे हैं तथा के वर्तमान मूल्य के साथ मैं होगा इस चर में की प्रतिलिपि बनाई गई है, इसलिए आपको परिणाम प्राप्त होगा जो पहली कोशिश से नैतिक रूप से अपेक्षित था।

मेरा सुझाव है, वह यह है कि जहां मैं बहुत-बहुत बहुत कुछ सीखा आप http://ejohn.org/apps/learn/ पर उत्कृष्ट ट्यूटोरियल को समझने के लिए बंद बेहतर समझने की कोशिश करने के लिए।

+4

भयानक उत्तर! धन्यवाद! –

+0

+1 वास्तव में बहुत बढ़िया जवाब। – Upperstage

46

... लेकिन सभी समारोह घोषणाओं के आस-पास के पिछले दौर के माता-पिता के बारे में क्या?

विशेष रूप से, यह जावास्क्रिप्ट को 'फ़ंक्शन() {...}' को इनलाइन अनाम फ़ंक्शन अभिव्यक्ति के रूप में परिभाषित करता है। आप कोष्ठक छोड़े गए हैं:

function() { 
    alert('hello'); 
}(); 

आपने एक सिंटैक्स त्रुटि प्राप्त करना चाहते हैं, क्योंकि जे एस पार्सर 'समारोह' कीवर्ड देख सकते हैं और यह मान लेगा कि एक समारोह बयान फार्म के शुरू कर रहे हैं:

function doSomething() { 
} 

... और आप एक समारोह नाम के बिना एक समारोह बयान नहीं हो सकता।

समारोह भाव और समारोह बयान दो अलग निर्माणों जो बहुत अलग तरीके से नियंत्रित किया जाता है कर रहे हैं। दुर्भाग्यवश वाक्यविन्यास लगभग समान है, इसलिए यह प्रोग्रामर को भ्रमित नहीं कर रहा है, यहां तक ​​कि पार्सर को यह भी कहने में कठिनाई है कि आपका मतलब क्या है!

1

this question देखें।यदि आप फ़ंक्शन नाम का उपयोग करते हैं तो ब्रांड्स का पहला सेट जरूरी नहीं है, लेकिन एक नामहीन फ़ंक्शन के लिए इस निर्माण की आवश्यकता होती है और कोष्ठक कोडर के लिए सेवा करते हैं ताकि वे यह महसूस कर सकें कि कोड ब्राउज़ करते समय वे एक स्व-चालान फ़ंक्शन देख रहे हैं (एक ब्लॉगर का best-practices recommendation देखें)।

+1

यदि आप एक नामित फ़ंक्शन का उपयोग कर रहे हैं तो आपको कोष्ठक की आवश्यकता है, लेकिन अगर आप उन्हें छोड़ सकते हैं एक चर के लिए एक फ़ंक्शन का परिणाम असाइन कर रहा है। यानि फ़ंक्शन myResult() {...}() विफल हो जाएगा लेकिन var myResult = function {...}() – wheresrhys

+0

काम करेगा आपके सर्वोत्तम प्रथाओं लिंक – David

5

विषय पर कुछ विचार:

  • कोष्टक:

    ब्राउज़र (इंजन/पार्सर) समारोह की तरह एक अभिव्यक्ति में

    [optional name]([optional parameters]){...code...} 
    

    तो उस कीवर्ड का समारोह एकत्रित करती है() {}() अंतिम संश्लेषण कोई समझ नहीं आता है।

    अब

    name=function(){} ; name() !? 
    

पर लगता है कि हाँ, कोष्ठक की पहली जोड़ी गुमनाम समारोह एक चर (संग्रहीत अभिव्यक्ति) में बदलने के लिए और दूसरा प्रक्षेपण मूल्यांकन/निष्पादन, तो ( समारोह के लिए मजबूर() {} )() समझ में आता है।

  • उपयोगिता:?

    1. लोड पर कुछ कोड निष्पादित करने के लिए और शेष पृष्ठ से उपयोग किए गए चर को अलग करने के लिए विशेष रूप से जब नाम विवाद संभव हो;

    2. eval ("स्ट्रिंग")

      (नया फंक्शन ("स्ट्रिंग"))() "= ?:" ऑपरेटर की तरह के लिए

    3. लपेटें लंबे कोड से बदलें:

      परिणाम = exp_to_test? (फ़ंक्शन() {... long_code ...})(): (फ़ंक्शन() {...})();

+0

में ग्रेट स्पष्टीकरण केस फ़ंक्शन नाम() {}() वैरिएबल नाम स्पष्ट रूप से बनाया गया है ताकि कोड परिभाषाओं के नाम के बाद ब्रेसिज़ को रखा जा सके(); – bortunac

14

juts क्या एंडी ह्यूम और अन्य लोगों ने कहा पर पालन करने के लिए:

'()' अज्ञात फ़ंक्शन आसपास के 'समूहीकरण ऑपरेटर' के रूप में की धारा 11.1.6 में परिभाषित किया गया है ईसीएमए स्पेक: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf

डॉक्स से शब्दशः लिया गया:

11.1.6 समूहीकरण ऑपरेटर

उत्पादन PrimaryExpression:

  1. वापसी का परिणाम: ( अभिव्यक्ति) के रूप में मूल्यांकन किया जाता है मूल्यांकन अभिव्यक्ति। यह प्रकार संदर्भ का हो सकता है।

इस संदर्भ में फ़ंक्शन को अभिव्यक्ति के रूप में माना जाता है।

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