स्वतः-निष्पादित अनाम जावास्क्रिप्ट फ़ंक्शंस के लिए कोष्ठक का स्थान?


107

मैं हाल ही में json2.js के वर्तमान संस्करण की तुलना उस संस्करण के साथ कर रहा था जो मैंने अपनी परियोजना में किया था और इस बात में अंतर देखा कि फ़ंक्शन एक्सप्रेशन को कैसे बनाया गया और स्वयं निष्पादित किया गया।

कोड को कोष्ठक में एक अनाम फ़ंक्शन लपेटने और फिर इसे निष्पादित करने के लिए उपयोग किया जाता है,

(function () {
  // code here
})();

लेकिन अब यह कोष्ठक में ऑटो-निष्पादित फ़ंक्शन लपेटता है।

(function () {
  // code here
}());

बता दें कि जावास्क्रिप्ट के एनकैप्सुलेटेड अनाम फ़ंक्शन सिंटैक्स के स्वीकृत उत्तर में CMS द्वारा एक टिप्पणी है कि "दोनों: (function(){})();और (function(){}());मान्य हैं।"

मैं सोच रहा था कि अंतर क्या है? क्या वैश्विक, अनाम फ़ंक्शन को छोड़कर पूर्व स्मृति को ऊपर ले जाता है? कोष्ठक कहाँ स्थित होना चाहिए?




1
इस निर्माण के उद्देश्य के बारे में भी पढ़ें , या ( तकनीकी ) स्पष्टीकरण की जाँच करें ( यहाँ भी )। कोष्ठक क्यों आवश्यक हैं, इस प्रश्न को देखें ।
बेरी जूल

जवाबों:


66

वे वास्तव में एक ही हैं।

पहला फ़ंक्शन एक वैध अभिव्यक्ति बनाने के लिए एक कोष्ठक के चारों ओर लपेटता है और इसे लागू करता है। अभिव्यक्ति का परिणाम अपरिभाषित है।

दूसरा फ़ंक्शन को निष्पादित करता है और स्वत: आहरण के चारों ओर कोष्ठक इसे एक वैध अभिव्यक्ति बनाते हैं। यह अपरिभाषित का मूल्यांकन भी करता है।

मुझे नहीं लगता कि ऐसा करने का एक "सही" तरीका है, क्योंकि अभिव्यक्ति का परिणाम समान है।

> function(){}()
SyntaxError: Unexpected token (
> (function(){})()
undefined
> (function(){return 'foo'})()
"foo"
> (function(){ return 'foo'}())
"foo"

8
JSLint चाहता है "(फ़ंक्शन () {} ());"। जेएसएलआईएनटी कहता है, "फंक्शन में इनवोकेशन ले जाएँ जिसमें फंक्शन हो।"
XP1

27
वास्तव में आप उन दो तक सीमित नहीं हैं, तो आप सिर्फ कुछ भी है कि संकलक एहसास समारोह एक अभिव्यक्ति का हिस्सा है और इस तरह के रूप में नहीं एक बयान है बनाता है के बारे में उपयोग कर सकते हैं +function(){}()या !function(){}()
TGR

49
@ XP1: JSLint बहुत सी ऐसी चीजें चाहता है जो क्रॉकफोर्ड की शैली के लिए विशिष्ट हैं, बजाय ठोस होने के। यह उनमें से एक है।
TJ क्राउडर

@TJCrowder। आप क्या सुझाव देंगे? jQuery पहली शैली का उपयोग करता है और क्रॉकफोर्ड दूसरे का उपयोग करता है।
तीज

4
@ThorpeObazee: यह वास्तव में कोई फर्क नहीं पड़ता, इसलिए जो भी आप पसंद करते हैं। मैं और अधिक उल्लंघन करनेवाला लोगों में से कुछ के खिलाफ की सलाह देते हैं ( -function(){}();, !function(){}();, और मूल रूप से किसी अन्य ऑपरेटर बस से पहले functionभी काम करते हैं, लेकिन मैं कोष्ठक का उपयोग कर संस्करणों के लिए छड़ी चाहते हैं)। मैं दूसरे को देखने की तुलना में पहले बहुत अधिक देखता हूं, और यह मेरी प्राथमिकता है; यह मेरे लिए और अधिक समझ में आता है, लेकिन यह व्यक्तिपरक है। FWIW: jsbin.com/ejaqow
TJ Crowder

13

उस मामले में यह कोई फर्क नहीं पड़ता। आप एक ऐसी अभिव्यक्ति का आह्वान कर रहे हैं जो पहली परिभाषा में एक फ़ंक्शन का निर्धारण करती है, और दूसरे उदाहरण में एक फ़ंक्शन को परिभाषित और तुरंत लागू करती है। वे समान हैं क्योंकि पहले उदाहरण में फ़ंक्शन एक्सप्रेशन केवल फ़ंक्शन परिभाषा है।

अभिव्यक्तियों को हल करने के लिए अन्य अधिक स्पष्ट रूप से उपयोगी मामले हैं:

(foo || bar)()

3
अन्य पाठकों के लिए स्पष्टीकरण के लिए (मुख्यतः क्योंकि मैं इसे पहले खुद समझ नहीं पाया :)), फू और / या बार पहले से ही कुछ फ़ंक्शन के बराबर होना चाहिए। (जैसे foo = function(){alert('hi');}। यदि न तो कोई फ़ंक्शन है, तो एक त्रुटि है।
अलेक्जेंडर बर्ड

3
@AlexanderBird एक और स्पष्टीकरण - यह भी एक त्रुटि फेंक देंगे अगर foo"सत्य" है, लेकिन फ़ंक्शन नहीं है।
JLRishe

9

वाक्य रचना से परे कोई अंतर नहीं है।

इसे करने की दूसरी विधि के बारे में अपनी चिंताओं के बारे में:

विचार करें:

(function namedfunc () { ... }())

namedfuncअभी भी वैश्विक दायरे में नहीं होगा, भले ही आपने नाम प्रदान किया हो। अनाम कार्यों के लिए भी यही जाता है। इसे उस दायरे में लाने का एकमात्र तरीका यह होगा कि इसे पारेंस के अंदर एक वैरिएबल को असाइन किया जाए।

((namedfunc = function namedfunc () { ... })())

बाहरी परते अनावश्यक हैं:

(namedfunc = function namedfunc () { ... })()

लेकिन आप चाहते हैं कि वैश्विक घोषणा वैसे भी, क्या आपने नहीं किया?

तो यह यह करने के लिए नीचे फोड़े:

(function namedfunc () { ... })()

और आप इसे और भी कम कर सकते हैं: नाम अनावश्यक है क्योंकि इसका उपयोग कभी नहीं किया जाएगा (जब तक कि आपका फ़ंक्शन पुनरावर्ती नहीं है .. और तब भी आप उपयोग कर सकते हैं arguments.callee)

(function () { ... })()

इस तरह से मैं इसके बारे में सोचता हूं (यह गलत हो सकता है, मैंने अभी तक ECMAScript विनिर्देश नहीं पढ़ा है)। आशा करता हूँ की ये काम करेगा।


ध्यान दें कि arguments.calleeES5 के बाद से पदावनत किया जाता है (और सख्त मोड में निषिद्ध)।
nyuszika7h

"बाहरी पार्स अनावश्यक हैं:" - मुझे लगता है कि वे त्रुटियों को रोकते हैं जब फाइलें संक्षिप्त होती हैं, अन्यथा आपको ए की आवश्यकता होगी! या कुछ और।
जिम्मी

-3

अंतर सिर्फ इसलिए है क्योंकि डगलस क्रॉकफोर्ड को आईआईएफई के लिए पहली शैली पसंद नहीं है ! (seriuosly) जैसा कि आप इस वीडियो में देख सकते हैं !!

अतिरिक्त रैपिंग (){दोनों शैलियों में) के अस्तित्व का एकमात्र कारण कोड फंक्शन एक्सप्रेशन के उस खंड को बनाने में मदद करना है , क्योंकि फ़ंक्शन घोषणा को तुरंत नहीं कहा जा सकता है। कुछ लिपियों / सिर्फ उपयोग कम करें-ईआरएस +, !, -और ~बजाय भी कोष्ठकों के। ऐशे ही:

+function() {  
    var foo = 'bar';  
}();

!function() {  
    var foo = 'bar';  
}();

-function() {  
    var foo = 'bar';  
}();

~function() {  
    var foo = 'bar';  
}();

और ये सभी आपके विकल्पों के समान हैं। इन मामलों में से चुनना पूरी तरह से अपने आप में है और इससे कोई फर्क नहीं पड़ता। {साथ लोगों ()का उत्पादन 1 बड़ा फ़ाइल बाइट ;-)}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.