जावास्क्रिप्ट समारोह अग्रणी धमाके! वाक्य - विन्यास


204

मैं अब कुछ पुस्तकालयों पर इस वाक्यविन्यास को देख रहा हूं और सोच रहा हूं कि लाभ क्या है। (नोट बंदी के बारे में अच्छी तरह से जानता हूं और कोड क्या कर रहा है, मैं केवल वाक्यात्मक अंतर के बारे में चिंतित हूं)

!function(){
  // do stuff
}();

अधिक सामान्य के विकल्प के रूप में

(function(){
  // do stuff
})();

स्वयं के लिए अनाम कार्यों को लागू करना।

मैं कुछ चीजें सोच रहा हूं। सबसे पहले, शीर्ष उदाहरण वास्तव में काम करने की अनुमति क्या है? इस कथन को क्रमबद्ध रूप से सही करने के लिए धमाके की आवश्यकता क्यों है? मुझे यह भी बताया गया है कि +काम करता है, और मुझे यकीन है कि इसके स्थान पर कुछ अन्य लोग भी हैं!

दूसरा, लाभ क्या है? मुझे केवल इतना बताया जा सकता है कि यह एक एकल चरित्र को बचाता है, लेकिन मैं कल्पना नहीं कर सकता कि कई अपनाने वालों को आकर्षित करने के लिए इतना बड़ा लाभ है। क्या मुझे कोई और लाभ है जो मुझे याद नहीं है?

केवल दूसरा अंतर जो मैं देख सकता हूं वह स्व-आहरण फ़ंक्शन का वापसी मूल्य होगा, लेकिन इन दोनों उदाहरणों में, हम फ़ंक्शन के वापसी मूल्य के बारे में वास्तव में परवाह नहीं करते हैं क्योंकि यह केवल एक क्लोजर बनाने के लिए उपयोग किया जाता है। तो क्या कोई मुझे बता सकता है कि कोई पहले वाक्यविन्यास का उपयोग क्यों कर सकता है?


फ्रेमवर्क कई पात्रों को बचाने के लिए पसंद करते हैं क्योंकि वे यह कर सकते हैं कि एक मिनीफायर अनुकूलित नहीं कर सकता है।
एलेक्स

पहला लाभ मेरे सिर पर आता है आप एक सैंडबॉक्स बना सकते हैं जैसे, (फ़ंक्शन ($) {...}) (jQuery);
जेएस टेलर

2
दोनों उदाहरण इसे प्राप्त करते हैं। जैसा कि उल्लेख किया गया है, मैं समझता हूं कि ये कार्य क्या कर रहे हैं, मैं वाक्यात्मक अंतरों में अधिक रुचि रखता हूं
brad

8
मैं इसे जरूरत के हिसाब से तैयार करता हूं, नेव, पिछले चालक दल की तुलना में अधिक परिष्कृत तरीके से प्यारा होने की आवश्यकता। "ओह, उन पैतृक हीथनों, हमें मिल गया है !!"
जेरेड फरिश

2
मुझे इस बारे में कभी नहीं पता था, कमाल। मुझे पसंद है !क्योंकि यह जोर देता है कि इसे निष्पादित किया जा रहा है।
cdmckay

जवाबों:


97

आदर्श रूप में आपको यह सब करने में सक्षम होना चाहिए:

function(){
  // do stuff
}(); 

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

तो इसे प्राप्त करने का सबसे छोटा रूप कुछ अभिव्यक्ति का उपयोग करना है जैसे कि UnaryExpression (और इसलिए CallExpression):

!function(){
  // do stuff
}(); 

या मजे के लिए:

-function(){
  // do stuff
}(); 

या:

+function(){
  // do stuff
}(); 

या और भी:

~function(){
  // do stuff
  return 0;
}( );

3
तो केवल लाभ terseness?
ब्रैड

12
मैंने उपरोक्त सभी विकल्पों को प्रदर्शन परीक्षण में जोड़ा है
Shaz

5
अभिव्यक्ति मैं कहूंगा। इस तरह के मामलों में गति वास्तव में मायने नहीं रखती है क्योंकि यह एक बार चलती है।
सी-स्माइल

1
जिज्ञासा से बाहर, मैंने देखा कि कोई भी धमाकेदार और धमाके सबसे तेज प्रदर्शन नहीं करता है, लेकिन कहीं न कहीं क्रोम के विकास में कम से कम, बैंग बिना किसी धमाके के तेजी से बन गया। (शायद सांख्यिकीय रूप से महत्वहीन लेकिन ...) क्या कोई कारण है? मैं हुड के नीचे कोड के बारे में ज्यादा नहीं जानता, लेकिन यह काफी आकर्षक है।
jmk2142

यदि आपका अर्धविराम गायब है तो आपके दो अपरिपक्व परिचालकों को द्विआधारी के रूप में व्याख्या किया जा सकता है। पहला और आखिरी उन उदाहरणों में सबसे सुरक्षित हैं।

73

जावास्क्रिप्ट में, एक रेखा के साथ शुरू functionहोने वाला एक फ़ंक्शन स्टेटमेंट होने की उम्मीद है और जैसा दिखता है

function doSomething() {
}

एक आत्म-आह्वान समारोह की तरह

function(){
  // do stuff
}();

उस रूप में फिट नहीं होता है (और पहले उद्घाटन पर कोई सिंटैक्स त्रुटि का कारण होगा क्योंकि कोई फ़ंक्शन नाम नहीं है), इसलिए कोष्ठक का उपयोग एक अनाम फ़ंक्शन अभिव्यक्ति को चित्रित करने के लिए किया जाता है ।

(function(){
  // do stuff
})();

लेकिन जो कुछ भी एक अभिव्यक्ति बनाता है (एक फ़ंक्शन स्टेटमेंट के विपरीत) वह करेगा, इसलिए इसलिए !। यह दुभाषिया को बता रहा है कि यह एक फ़ंक्शन स्टेटमेंट नहीं है। इसके अलावा, ऑपरेटर पूर्वता यह तय करती है कि फ़ंक्शन को नकार से पहले लागू किया गया है।

मुझे इस सम्मेलन के बारे में पता नहीं था, लेकिन अगर यह सामान्य हो जाता है तो यह पठनीयता में योगदान दे सकता है। मेरा मतलब यह है कि !functionकोड के एक बड़े ब्लॉक के शीर्ष पर पढ़ने वाले किसी व्यक्ति को एक आत्म-आह्वान की उम्मीद होगी, जिस तरह से हम देखते हैं उसी तरह की अपेक्षा करने के लिए पहले से ही वातानुकूलित हैं (function। सिवाय इसके कि हम उन कष्टप्रद कोष्ठकों को खो देंगे। मुझे उम्मीद है कि गति या चरित्र गणना में किसी भी बचत के विपरीत, यही कारण है।


यह "फ़ंक्शन के साथ शुरू होने वाली लाइन की उम्मीद है ..." काफी फजी लग रहा है। इसके बारे में क्या:var foo = {CR/LF here} function bar() {}
c-मुस्कान

45

पहले से ही कहा गया था कि चीजों के अलावा, के साथ वाक्यविन्यास! उपयोगी है यदि आप अर्धविराम के बिना जावास्क्रिप्ट लिखते हैं:

var i = 1
!function(){
  console.log('ham')
}()

i = 2
(function(){
  console.log('cheese')
})()

पहला उदाहरण उम्मीद के मुताबिक 'हैम' का उत्पादन करता है, लेकिन दूसरा एक त्रुटि फेंक देगा क्योंकि निम्नलिखित पेरेंटिस के कारण i = 2 स्टेटमेंट को समाप्त नहीं किया गया है।

साथ ही अगर आपके पूर्ववर्ती कोड में अर्धविराम मौजूद हैं, तो संक्षिप्त जावास्क्रिप्ट फ़ाइलों में आपको चिंता करने की ज़रूरत नहीं है। तो आम की कोई आवश्यकता नहीं है; (फ़ंक्शन () {}) (); यह सुनिश्चित करने के लिए कि आपका अपना टूटेगा नहीं।

मुझे पता है कि मेरा जवाब थोड़ा देर से है लेकिन मुझे लगता है कि यह अभी तक उल्लेख नहीं किया गया है :)


6
टिप और यादों के लिए +1 ... कोई भी इन दिनों अर्धविराम के बिना जावास्क्रिप्ट लिखना पसंद नहीं करता है।
पाब्लो ग्रिसफ़ी

4
ट्विटर बूटस्ट्रैप अर्धविराम के बिना सभी जेएस है, और यह बहुत नया है ... (क्षमा करें, अगर उपरोक्त टिप्पणी प्रकृति में व्यंग्यात्मक थी और मैं इसे याद कर रहा था)।
ब्रांडवाफल

2
यह वास्तव में सच नहीं है। निम्नलिखित उदाहरण पर विचार करें: फ़ंक्शन () (कंसोल) ("हैम");} (); फ़ंक्शन () {कंसोल.लॉग ("पनीर")} (); आपको एक त्रुटि मिलती है: "सिंटैक्स्योर: अनपेक्षित टोकन!"
हैवीशर

हाँ आप सही है। यदि आपने उन्हें उसी पंक्ति में रखा है, तो एक त्रुटि है। मैंने उसके बारे में नहीं सोचा। लेकिन, अब तक मेरे द्वारा इस्तेमाल की गई कोई भी पटकथा / लिपि नहीं है। और जब आप अपनी फ़ाइलों को छोटा और संक्षिप्त करते हैं तो अर्धविराम जोड़े जाते हैं। इसलिए, ईमानदारी से, मैं एक ऐसे मामले की कल्पना नहीं कर सकता जहाँ आप उस समस्या में भाग लेंगे। दूसरी ओर, यह यहाँ 2 बजे है और मैं अज्ञानी हो सकता हूं :)
स्मो

6

एक बात के लिए, jsPerf दिखाता है कि !आमतौर पर (UnaryExpression) का उपयोग करना तेज है। कभी-कभी वे समान होने के लिए निकलते हैं, लेकिन जब वे नहीं होते हैं, तो मैंने गैर-धमाकेदार एक जीत को दूसरों पर बहुत अधिक नहीं देखा है: http://jsperf.com/bang-function

यह सबसे पुराने (प्रति कहना ..) क्रोम, संस्करण 8 के साथ नवीनतम उबंटू पर परीक्षण किया गया था। इसलिए परिणाम निश्चित रूप से भिन्न हो सकते हैं।

संपादित करें: कैसे के बारे में कुछ पागल की तरह delete?

delete function() {
   alert("Hi!"); 
}();

या void?

void function() {
   alert("Hi!"); 
}();

दिलचस्प! मुझे लगभग 50/50 मिले हालांकि सफारी स्पीड-वार में, गैर-धमाकेदार निश्चित रूप से अपने पास रखा। मुझे आश्चर्य है कि क्या संभावित गति अंतर के लिए कुछ सिद्धांत है?
ब्रैड

@ ब्रैड को सफारी के साथ कुछ करना चाहिए, यदि आप परीक्षणों को देखते हैं, तो अधिकांश अन्य ब्राउज़र अनुकूल प्रतीत होते हैं !। लेकिन मैं इस पर भी एक सिद्धांत ढूंढना चाहूंगा :)
Shaz

3
मुझे शून्य पसंद है क्योंकि यह स्पष्ट रूप से कह रहा है "मुझे रिटर्न वैल्यू की परवाह नहीं है", और क्योंकि यह मुझे अन्य भाषाओं में सम्मेलनों की याद दिलाता है
code_monk

4

जैसा कि आप यहाँ देख सकते हैं , जावास्क्रिप्ट में स्व-चालित विधियों को करने का सबसे अच्छा तरीका है:

(function(){}()); -> 76,827,475 ops/sec

!function(){}();  -> 69,699,155 ops/sec

(function(){})(); -> 69,564,370 ops/sec

1
मुझे संदेह है कि प्रदर्शन एक वाक्यविन्यास या दूसरे का उपयोग करने का कारण है। 70M ऑप्स / सेकंड में, बंद करने की घोषणा करना कोड के अंदर वैसे भी हजारों गुना तेजी से होने जा रहा है
एलोइम्स

3

तो, नकारात्मक के साथ "!" और +, -, ~, ~, हटाना, शून्य जैसे अन्य सभी अपरिपक्व परिचालकों को बहुत कुछ बताया गया है, बस योग करने के लिए:

!function(){
  alert("Hi!");
}(); 

या

void function(){
  alert("Hi!");
}();

या

delete function(){
  alert("Hi!");
}();

और मज़ा के लिए बाइनरी ऑपरेटरों के साथ कुछ और मामले :)

1 > function() {
   alert("Hi!"); 
}();

या

1 * function() {
   alert("Hi!"); 
}();

या

1 >>> function() {
   alert("Hi!"); 
}();

या और भी

1 == function() {
   alert("Hi!"); 
}();

किसी और लोगों के लिए टर्नरी छोड़ना :)


12
0?0:function() { alert("Hi!"); }();
daniel1426

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