जावास्क्रिप्ट में, आप इसका उपयोग कब करना चाहेंगे:
(function(){
//Bunch of code...
})();
इस पर:
//Bunch of code...
जावास्क्रिप्ट में, आप इसका उपयोग कब करना चाहेंगे:
(function(){
//Bunch of code...
})();
इस पर:
//Bunch of code...
जवाबों:
यह चर स्कूपिंग के बारे में है। सेल्फ एग्जीक्यूटिंग फंक्शन में घोषित वेरिएबल्स, डिफ़ॉल्ट रूप से, सेल्फ एक्जीक्यूटिंग फंक्शन के कोड के लिए उपलब्ध होते हैं। यह इस बात की परवाह किए बिना कोड लिखने की अनुमति देता है कि जावास्क्रिप्ट कोड के अन्य ब्लॉकों में चर का नाम कैसे दिया जाता है।
उदाहरण के लिए, जैसा कि अलेक्जेंडर ने एक टिप्पणी में उल्लेख किया है :
(function() {
var foo = 3;
console.log(foo);
})();
console.log(foo);
यह पहले लॉग करेगा 3
और फिर अगले पर एक त्रुटि फेंक देगा console.log
क्योंकि foo
परिभाषित नहीं है।
var
इस तरह से बिना करते हैं ...function(){ foo=3;}
:? यह वैश्विक वैरिएबल सेट करेगा, है ना?
function(){ var foo = 3; alert(foo); }; alert(foo);
इसलिए मुझे अभी भी नहीं मिला है
सरलीकृत। बहुत सामान्य लग रही है, इसकी लगभग आराम:
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
हालाँकि, क्या होगा यदि मैं अपने पृष्ठ के लिए एक बहुत आसान जावास्क्रिप्ट पुस्तकालय को शामिल करूँ जो अपने आधार स्तर अभ्यावेदन में उन्नत वर्णों का अनुवाद करे?
रुको क्या?
मेरा मतलब है, अगर कोई इस पर किसी तरह के उच्चारण के साथ एक चरित्र में टाइप करता है, लेकिन मैं केवल अपने कार्यक्रम में 'अंग्रेजी' अक्षर AZ चाहता हूं? खैर ... स्पेनिश 'ñ' और फ्रेंच 'é' वर्णों का अनुवाद 'n' और 'e' के आधार वर्णों में किया जा सकता है।
तो किसी अच्छे व्यक्ति ने एक व्यापक चरित्र कनवर्टर लिखा है कि मैं अपनी साइट में शामिल कर सकता हूं ... मैं इसे शामिल करता हूं।
एक समस्या: इसमें एक फंक्शन है जिसे 'नेम' कहा जाता है जो मेरे फंक्शन के समान है।
इसे ही टक्कर कहा जाता है। हम दो कार्य ही में घोषित मिल गया है गुंजाइश ही नाम के साथ। हम इससे बचना चाहते हैं।
इसलिए हमें किसी तरह अपने कोड को स्कोप करने की जरूरत है।
जावास्क्रिप्ट में कोड को स्कोप करने का एकमात्र तरीका इसे एक फ़ंक्शन में लपेटना है:
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
यह हमारी समस्या का समाधान हो सकता है। सब कुछ अब संलग्न है और केवल हमारे उद्घाटन और समापन ब्रेसिज़ के भीतर से ही पहुँचा जा सकता है।
हमारे पास एक फ़ंक्शन है ... जो देखने में अजीब है, लेकिन पूरी तरह से कानूनी है।
केवल एक समस्या। हमारा कोड काम नहीं करता है। हमारे उपयोगकर्ता नाम चर कंसोल में कभी भी गूँजते नहीं हैं!
हम अपने मौजूदा कोड ब्लॉक के बाद अपने फ़ंक्शन में कॉल जोड़कर इस समस्या को हल कर सकते हैं ...
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
main();
या पहले!
main();
function main() {
// We are now in our own sound-proofed room and the
// character-converter libarary's name() function can exist at the
// same time as ours.
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
एक माध्यमिक चिंता: क्या संभावना है कि 'मुख्य' नाम का अभी तक उपयोग नहीं किया गया है? ... तो बहुत, बहुत पतला।
हमें और अधिक परिमार्जन की आवश्यकता है। और हमारे मुख्य () फ़ंक्शन को स्वचालित रूप से निष्पादित करने का कुछ तरीका।
अब हम ऑटो-एक्ज़ीक्यूशन फ़ंक्शंस (या सेल्फ-एक्ज़ीक्यूटिंग, सेल्फ-रनिंग, जो भी हो) पर आते हैं।
((){})();
वाक्य-विन्यास पाप के रूप में अजीब है। हालाँकि, यह काम करता है।
जब आप कोष्ठक में फ़ंक्शन परिभाषा लपेटते हैं, और इसमें एक पैरामीटर सूची (एक और सेट या कोष्ठक!) शामिल होती है, तो यह फ़ंक्शन कॉल के रूप में कार्य करती है ।
तो कुछ स्व-निष्पादित सिंटैक्स के साथ हमारे कोड को फिर से देखें:
(function main() {
var userName = "Sean";
console.log(name());
function name() {
return userName;
}
}
)();
इसलिए, आपके द्वारा पढ़े जाने वाले अधिकांश ट्यूटोरियल्स में, आप अब 'अनाम सेल्फ-एक्जीक्यूटिंग' या कुछ इसी तरह के शब्द के साथ बमबारी करेंगे।
व्यावसायिक विकास के कई वर्षों के बाद, मैं दृढ़ता से नाम के लिए आप से आग्रह करता हूं कि हर समारोह आप लिखते हैं डीबगिंग उद्देश्यों के लिए।
जब कुछ गलत होगा (और यह होगा), तो आप अपने ब्राउज़र में बैकट्रेस की जाँच करेंगे। यह है हमेशा अपने कोड मुद्दों संकीर्ण करने के लिए स्टैक ट्रेस में प्रविष्टियों नाम है जब आसान!
बेहद लंबी हवा और मुझे उम्मीद है कि यह मदद करता है!
:)
सेल्फ-इनवोकेशन (जिसे ऑटो-इनवोकेशन भी कहा जाता है) तब होता है जब कोई फ़ंक्शन अपनी परिभाषा पर तुरंत अमल करता है। यह एक कोर पैटर्न है और जावास्क्रिप्ट विकास के कई अन्य पैटर्न की नींव के रूप में कार्य करता है।
मैं इसका बहुत बड़ा प्रशंसक हूं: क्योंकि
निष्ठा से - (आपको इसका भला क्यों कहना चाहिए?)
अधिक यहाँ ।
नेमस्पेसिंग। जावास्क्रिप्ट के स्कोप फ़ंक्शन-स्तर हैं।
मुझे विश्वास नहीं है कि उत्तर में से कोई भी उल्लिखित ग्लोबल्स का उल्लेख नहीं करता है।
(function(){})()
निर्माण,, निहित वैश्विक खिलाफ की रक्षा नहीं करता है जो मेरे लिए बड़ा चिंता का विषय है देखना http://yuiblog.com/blog/2006/06/01/global-domination/
मूल रूप से फ़ंक्शन ब्लॉक यह सुनिश्चित करता है कि आपके द्वारा परिभाषित सभी निर्भर "वैश्विक संस्करण" आपके कार्यक्रम तक ही सीमित हैं, यह अंतर्निहित ग्लोबल्स को परिभाषित करने से आपकी रक्षा नहीं करता है। JSHint या इस तरह के व्यवहार के खिलाफ बचाव के बारे में सिफारिशें प्रदान कर सकते हैं।
अधिक संक्षिप्त var App = {}
सिंटैक्स एक समान स्तर की सुरक्षा प्रदान करता है, और 'सार्वजनिक' पृष्ठों पर फ़ंक्शन ब्लॉक में लपेटा जा सकता है। ( इस निर्माण का उपयोग करने वाले पुस्तकालयों के वास्तविक विश्व उदाहरणों के लिए Ember.js या SproutCore देखें )
जहां तक private
गुण चलते हैं, वे एक तरह से ओवररेटेड हैं जब तक कि आप एक सार्वजनिक ढांचा या लाइब्रेरी नहीं बना रहे हैं, लेकिन अगर आपको उन्हें लागू करने की आवश्यकता है, तो डगलस क्रॉकफोर्ड के पास कुछ अच्छे विचार हैं।
मैं सभी जवाब पढ़ा है, कुछ बहुत ही महत्वपूर्ण यहाँ याद आ रही है , मैं चुंबन होगा। 2 मुख्य कारण हैं, मुझे स्व -एक्ज़ीक्यूटिंग बेनामी फ़ंक्शंस की आवश्यकता क्यों है, या बेहतर कहा गया " तत्काल-इनवॉल्ड फंक्शन एक्सप्रेशन (IIFE) ":
पहले वाले को बहुत अच्छे से समझाया गया है। दूसरे के लिए, कृपया निम्नलिखित उदाहरण का अध्ययन करें:
var MyClosureObject = (function (){
var MyName = 'Michael Jackson RIP';
return {
getMyName: function () { return MyName;},
setMyName: function (name) { MyName = name}
}
}());
ध्यान 1: हम किसी फ़ंक्शन को असाइन नहीं कर रहे हैं MyClosureObject
, आगे उस फ़ंक्शन को लागू करने का परिणाम है । ()
अंतिम पंक्ति में अवगत रहें ।
ध्यान 2: आप जावास्क्रिप्ट में कार्यों के बारे में क्या जानते हैं इसके अलावा यह है कि आंतरिक कार्यों को कार्यों के मापदंडों और चर तक पहुंच मिलती है , वे भीतर परिभाषित होते हैं।
आइए हम कुछ प्रयोग आजमाएँ:
मैं MyName
उपयोग कर सकता हूँ getMyName
और यह काम करता है:
console.log(MyClosureObject.getMyName());
// Michael Jackson RIP
निम्नलिखित सरल दृष्टिकोण काम नहीं करेगा:
console.log(MyClosureObject.MyName);
// undefined
लेकिन मैं एक और नाम निर्धारित कर सकता हूं और अपेक्षित परिणाम प्राप्त कर सकता हूं:
MyClosureObject.setMyName('George Michael RIP');
console.log(MyClosureObject.getMyName());
// George Michael RIP
संपादित करें: उपर्युक्त उदाहरण MyClosureObject
में new
उपसर्ग के बिना उपयोग किए जाने के लिए डिज़ाइन किया गया है , इसलिए सम्मेलन द्वारा इसे पूंजीकृत नहीं किया जाना चाहिए।
क्या कोई पैरामीटर है और "बंच ऑफ कोड" एक फ़ंक्शन देता है?
var a = function(x) { return function() { document.write(x); } }(something);
बंद। something
को दिए गए फ़ंक्शन द्वारा उपयोग किए जाने वाले मान का मान a
। something
कुछ अलग मान हो सकता है (लूप के लिए) और हर बार एक नया फ़ंक्शन होता है।
var x = something;
में बाहरी फ़ंक्शन में एक स्पष्ट पसंद करता हूं x
, हालांकि: इसके अलावा यह इस तरह से अधिक पठनीय है ...
x
और लेक्सिकल स्कोप पर सीधे निर्भर करते हैं , तो इसका नया मूल्य उपयोग किया जाएगा , अर्थात document.write(something)
...
स्कोप आइसोलेशन, हो सकता है। ताकि फ़ंक्शन घोषणा के अंदर चर बाहरी नाम स्थान को प्रदूषित न करें।
बेशक, वहाँ से बाहर जेएस कार्यान्वयन के आधे पर, वे वैसे भी होगा।
यहाँ एक ठोस उदाहरण है कि कैसे एक आत्मघाती अनाम फ़ंक्शन उपयोगी हो सकता है।
for( var i = 0; i < 10; i++ ) {
setTimeout(function(){
console.log(i)
})
}
आउटपुट: 10, 10, 10, 10, 10...
for( var i = 0; i < 10; i++ ) {
(function(num){
setTimeout(function(){
console.log(num)
})
})(i)
}
आउटपुट: 0, 1, 2, 3, 4...
let
के एवज में var
पहला मामला ठीक हो जाएगा।
चूंकि जावास्क्रिप्ट में फ़ंक्शंस प्रथम श्रेणी की वस्तु हैं, इसे इस तरह परिभाषित करके, यह प्रभावी रूप से C ++ या C # की तरह "क्लास" को परिभाषित करता है।
यह फ़ंक्शन स्थानीय चरों को परिभाषित कर सकता है, और इसके भीतर कार्य कर सकता है। आंतरिक कार्यों (प्रभावी रूप से उदाहरण के तरीकों) में स्थानीय चर (प्रभावी रूप से चर) तक पहुंच होगी, लेकिन वे बाकी स्क्रिप्ट से अलग हो जाएंगे।
जावास्क्रिप्ट में स्व-संलग्न समारोह:
एक आत्म-आह्वान अभिव्यक्ति का आह्वान किया जाता है (शुरू), स्वचालित रूप से, बिना बुलाए। एक स्व-आह्वान अभिव्यक्ति का सृजन इसके ठीक बाद किया जाता है। यह मूल रूप से नामकरण संघर्ष से बचने के साथ-साथ एनकैप्सुलेशन प्राप्त करने के लिए उपयोग किया जाता है। इस फ़ंक्शन के बाहर चर या घोषित ऑब्जेक्ट सुलभ नहीं हैं। न्यूनतमकरण (फ़ाइल नाम) की समस्याओं से बचने के लिए, हमेशा स्व निष्पादित कार्य का उपयोग करें।
वैरिएबल के दायरे को प्रबंधित करने के लिए सेल्फ एक्जीक्यूटिंग फंक्शन का उपयोग किया जाता है।
एक चर का दायरा आपके कार्यक्रम का क्षेत्र है जिसमें इसे परिभाषित किया गया है।
एक वैश्विक चर में वैश्विक गुंजाइश है; यह आपके जावास्क्रिप्ट कोड में हर जगह परिभाषित किया गया है और स्क्रिप्ट में कहीं से भी पहुँचा जा सकता है, यहां तक कि आपके कार्यों में भी। दूसरी ओर, किसी फ़ंक्शन के भीतर घोषित चर केवल फ़ंक्शन के निकाय के भीतर परिभाषित किए जाते हैं। वे स्थानीय चर हैं, स्थानीय गुंजाइश है और केवल उस फ़ंक्शन के भीतर ही पहुँचा जा सकता है। फ़ंक्शन मापदंडों को स्थानीय चर के रूप में भी गिना जाता है और केवल फ़ंक्शन के शरीर के भीतर परिभाषित किया जाता है।
जैसा कि नीचे दिखाया गया है, आप अपने फ़ंक्शन के अंदर Globalvariable चर का उपयोग कर सकते हैं और यह भी ध्यान दें कि फ़ंक्शन के मुख्य भाग के भीतर, एक स्थानीय चर समान नाम के साथ वैश्विक चर पर पूर्वता लेता है।
var globalvar = "globalvar"; // this var can be accessed anywhere within the script
function scope() {
alert(globalvar);
localvar = "localvar" //can only be accessed within the function scope
}
scope();
इसलिए मूल रूप से एक स्व-निष्पादित फ़ंक्शन कोड को इस बात की परवाह किए बिना लिखा जा सकता है कि जावास्क्रिप्ट कोड के अन्य ब्लॉकों में चर का नाम कैसे दिया जाता है।
(function(){
var foo = {
name: 'bob'
};
console.log(foo.name); // bob
})();
console.log(foo.name); // Reference error
दरअसल, उपरोक्त फ़ंक्शन को एक नाम के बिना फ़ंक्शन अभिव्यक्ति के रूप में माना जाएगा।
करीब और खुले कोष्ठक के साथ एक समारोह को लपेटने का मुख्य उद्देश्य वैश्विक अंतरिक्ष को प्रदूषित करने से बचाना है।
फ़ंक्शन अभिव्यक्ति के अंदर चर और फ़ंक्शन निजी हो गए (अर्थात) वे फ़ंक्शन के बाहर उपलब्ध नहीं होंगे।
संक्षिप्त उत्तर है: ग्लोबल (या उच्चतर) दायरे के प्रदूषण को रोकने के लिए।
IIFE (तुरंत इनवाइटेड फंक्शन एक्सप्रेशन) स्क्रिप्ट लिखने के लिए सबसे अच्छा अभ्यास है, जो प्लग-इन, ऐड-ऑन, उपयोगकर्ता स्क्रिप्ट या जो भी स्क्रिप्ट अन्य लोगों की स्क्रिप्ट के साथ काम करने की उम्मीद है । यह सुनिश्चित करता है कि आपके द्वारा परिभाषित कोई भी चर अन्य लिपियों पर अवांछित प्रभाव नहीं देता है।
यह IIFE अभिव्यक्ति लिखने का दूसरा तरीका है। मैं व्यक्तिगत रूप से इस निम्नलिखित विधि को पसंद करता हूं:
void function() {
console.log('boo!');
// expected output: "boo!"
}();
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void
ऊपर दिए गए उदाहरण से यह बहुत स्पष्ट है कि IIFE दक्षता और प्रदर्शन को भी प्रभावित कर सकता है, क्योंकि जिस फ़ंक्शन को केवल एक बार चलाने की उम्मीद है, उसे एक बार निष्पादित किया जाएगा और फिर अच्छे के लिए शून्य में डंप किया जाएगा । इसका मतलब है कि फ़ंक्शन या विधि घोषणा स्मृति में नहीं रहती है।
void
पहले का उपयोग नहीं देखा था । मुझें यह पसंद है।
ऐसा लगता है कि इस प्रश्न का उत्तर सभी तैयार है, लेकिन मैं अपने इनपुट को वैसे भी पोस्ट करूंगा।
मुझे पता है कि कब मुझे सेल्फ-एक्जीक्यूटिंग फंक्शंस का इस्तेमाल करना पसंद है।
var myObject = {
childObject: new function(){
// bunch of code
},
objVar1: <value>,
objVar2: <value>
}
फ़ंक्शन मुझे कुछ अतिरिक्त कोड का उपयोग करने की अनुमति देता है ताकि चाइल्डऑब्जेक्ट्स विशेषताओं और संपत्तियों को क्लीनर कोड के रूप में परिभाषित किया जा सके, जैसे आमतौर पर उपयोग किए जाने वाले चर सेट करना या गणित के समीकरणों को निष्पादित करना; ओह! या त्रुटि जाँच। के रूप में करने के लिए सीमित करने के लिए विरोध किया जा रहा है नेस्टेड वस्तु तात्कालिक वाक्य रचना ...
object: {
childObject: {
childObject: {<value>, <value>, <value>}
},
objVar1: <value>,
objVar2: <value>
}
सामान्य रूप से कोडिंग में बहुत सारे समान काम करने के अस्पष्ट तरीके होते हैं, जिससे आपको आश्चर्य होता है, "परेशान क्यों?" लेकिन नई परिस्थितियां पॉप अप करती रहती हैं जहां आप अब केवल बुनियादी / मूल प्रिंसिपलों पर भरोसा नहीं कर सकते हैं।
आपके सरल प्रश्न को देखते हुए: "जावास्क्रिप्ट में, आप इसका उपयोग कब करना चाहेंगे: ..."
मुझे @ken_browning और @ sean_holding के उत्तर पसंद हैं, लेकिन यहां एक और उपयोग-मामला है जिसका उल्लेख मैंने नहीं किया है:
let red_tree = new Node(10);
(async function () {
for (let i = 0; i < 1000; i++) {
await red_tree.insert(i);
}
})();
console.log('----->red_tree.printInOrder():', red_tree.printInOrder());
जहां Node.insert कुछ अतुल्यकालिक कार्रवाई है।
मैं अपने फ़ंक्शन की घोषणा के समय केवल async कीवर्ड के बिना प्रतीक्षा नहीं कर सकता, और मुझे बाद में उपयोग के लिए नामांकित फ़ंक्शन की आवश्यकता नहीं है, लेकिन उस इंसर्ट कॉल का इंतजार करने की आवश्यकता है या मुझे कुछ अन्य समृद्ध सुविधाओं (जो जानता है?) की आवश्यकता है ।
IIRC यह आपको निजी गुण और विधियाँ बनाने की अनुमति देता है।