जावास्क्रिप्ट में फ़ंक्शन (फ़ंक्शन () {}) () क्या है?


790

मुझे पता था कि इसका क्या मतलब है, लेकिन मैं अब संघर्ष कर रहा हूं ...

क्या यह मूल रूप से कह रहा है document.onload?

(function () {

})();

20
btw, हालाँकि आप लोगों को इस समारोह को 'आत्म-आह्वान' करते देखेंगे, यह स्पष्ट रूप से सच नहीं है। Iife शब्द में सटीकता का लाभ है।
1

6
यह इस निर्माण का एक शानदार विवरण देता है। यह वह जगह भी है जहाँ "IIFE" शब्द की उत्पत्ति हुई है। benalman.com/news/2010/11/…
jeremysawesome


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

जवाबों:


854

यह एक तत्काल-आमंत्रित समारोह अभिव्यक्ति है , या संक्षेप में IIFE है। इसे बनाने के तुरंत बाद इसे क्रियान्वित किया जाता है।

इसका किसी भी इवेंट (जैसे document.onload) के लिए किसी भी इवेंट-हैंडलर से कोई लेना-देना नहीं है ।
कोष्ठक की पहली जोड़ी के भीतर भाग पर विचार करें: .... यह एक नियमित कार्य अभिव्यक्ति है। फिर अंतिम जोड़ी को देखें , यह आम तौर पर एक फ़ंक्शन को कॉल करने के लिए एक अभिव्यक्ति में जोड़ा जाता है; इस मामले में, हमारी पूर्व अभिव्यक्ति।(function(){})();(function(){})();

ग्लोबल नेमस्पेस को प्रदूषित करने से बचने के लिए इस पैटर्न का उपयोग अक्सर किया जाता है, क्योंकि IIFE (किसी अन्य सामान्य फ़ंक्शन की तरह) में उपयोग किए जाने वाले सभी चर इसके दायरे से बाहर दिखाई नहीं देते हैं।
यही कारण है कि, हो सकता है, आपने इस निर्माण को इवेंट-हैंडलर के साथ भ्रमित कर दिया हो window.onload, क्योंकि यह अक्सर इस रूप में उपयोग किया जाता है:

(function(){
  // all your code here
  var foo = function() {};
  window.onload = foo;
  // ...
})();
// foo is unreachable here (it’s undefined)

गुफ़ा द्वारा सुझाए गए सुधार :

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

अपडेट करें क्योंकि यह एक बहुत लोकप्रिय विषय है, यह ध्यान देने योग्य है कि IIFE को ES6 के एरो फ़ंक्शन के साथ भी लिखा जा सकता है (जैसे कि गजस ने एक टिप्पणी में बताया है ):

((foo) => {
 // do something with foo here foo
})('foo value')

@ gion_13 निर्माण चरण और पार्स चरण के बीच अंतर क्या है?
एकवंतोर्ड

1
@ जेली जिस तरह से मैं इसे देखता हूं, एक जेएस प्रोग्राम के जीवन चक्र में निम्नलिखित चरण शामिल हैं: पार्सिंग, निर्माण / संकलन, निष्पादन। यद्यपि वास्तविक कार्यान्वयन (और नामकरण :)) ब्राउज़र से ब्राउज़र में भिन्न हो सकता है, हम पार्सिंग त्रुटियों, फहराए जाने और समय की त्रुटियों को देखने के लिए अपने कोड में इन चरणों को निर्धारित कर सकते हैं। मुझे व्यक्तिगत रूप से इस पर कई संसाधन नहीं मिले हैं क्योंकि यह बहुत निम्न स्तर का है और यह ऐसा कुछ नहीं है जिसे प्रोग्रामर नियंत्रित कर सकता है। आप इस SO पोस्ट में किसी प्रकार की व्याख्या पा सकते हैं: stackoverflow.com/a/34562772/491075
gion_13

@sam सभी का फेरट, वहाँ varianle घोषणा और नए खोजशब्द है। इसका मतलब यह है कि आपके उदाहरण में आप इसे कंस्ट्रक्टर (अनाम फ़ंक्शन एक्सप्रेशन) द्वारा परिभाषित एक नए आक्षेप का संकेत दे रहे हैं और इसे नए ऑपरेटर के माध्यम से आमंत्रित किया गया है, न कि आईआईएफई उदाहरण के रूप में वित्त को कॉल करके। यकीन है कि यह कार्य सामग्री के लिए एक बंद की तरह काम करता है, लेकिन यह अब तक एक अलग उपयोग मामला है।
gion_13

यह वैश्विक नामस्थान को कैसे प्रदूषित कर रहा है? foo फ़ंक्शन वैसे भी बाहर उपलब्ध नहीं है। function(){ var foo = '5'; }
पंकज

1
@ पंकज - खुद के द्वारा लिया गया, जो वाक्य-रचना की मान्य जेएस भी नहीं है (यह एक फ़ंक्शन अभिव्यक्ति है लेकिन अभिव्यक्ति के संदर्भ में नहीं है इसलिए इसे सिंटैक्स त्रुटि के रूप में माना जाता है)।
क्वेंटिन

109

यह सिर्फ एक अनाम फ़ंक्शन है जिसे सही बनाया जाने के बाद निष्पादित किया जाता है।

यह वैसा ही है जैसे कि आपने इसे एक चर को सौंपा है, और इसका उपयोग इसके ठीक बाद किया है, केवल चर के बिना:

var f = function () {
};
f();

JQuery में एक समान निर्माण है जिसके बारे में आप सोच रहे होंगे:

$(function(){
});

यह readyघटना को बांधने का संक्षिप्त रूप है :

$(document).ready(function(){
});

लेकिन उपरोक्त दोनों निर्माण IIFE s नहीं हैं ।


83
पिछले दो वास्तव में IIFEs नहीं हैं, क्योंकि जब वे DOM तैयार होते हैं, तो उन्हें तुरंत
बुला

15
@swordofpain: हां, यह सही है, वे IIFE नहीं हैं।
गुफ़ा

दूसरी स्निपेट पर विचार करने वाले @swordofpain; फ़ंक्शन के अंत में इसे IIFE में बदलकर कोई भी मूल्य होगा?
टाइमबैंडिट

क्या अर्धविराम अंत में आवश्यक है?
FrenkyB

@FrenkyB आवश्यक नहीं, नहीं, लेकिन प्रोत्साहित (अर्धविराम वास्तव में जावास्क्रिप्ट में वास्तव में आवश्यक नहीं हैं, लेकिन यह अच्छा अभ्यास है)। उनमें से प्रत्येक ऐसे वक्तव्य हैं जो फ़ंक्शन फ़ंक्शन की घोषणा के बजाय अनाम फ़ंक्शन को शामिल करने के लिए होते हैं।
लेडिविन

52

एक तुरंत-आमंत्रित फ़ंक्शन अभिव्यक्ति (IIFE) तुरंत एक फ़ंक्शन को कॉल करता है। इसका सीधा सा मतलब है कि परिभाषा के पूरा होने के तुरंत बाद फ़ंक्शन निष्पादित किया जाता है।

तीन और सामान्य शब्द:

// Crockford's preference - parens on the inside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
}());

//The OPs example, parentheses on the outside
(function() {
  console.log('Welcome to the Internet. Please follow me.');
})();

//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
  console.log('Welcome to the Internet. Please follow me.');
}();

यदि इसके वापसी मूल्य के लिए कोई विशेष आवश्यकताएं नहीं हैं, तो हम लिख सकते हैं:

!function(){}();  // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}();  // => NaN

वैकल्पिक रूप से, यह हो सकता है:

~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();

आप भी लिख सकते हैं:

new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required

4
पिछले एक 31.new'अमान्य सिंटैक्स है
बिल्ली

9
एक ही चीज़ को लिखने के इतने तरीके क्यों हैं? !! > _ <मुझे यह भाषा पसंद नहीं है
Awesome_girl

6
औरंद विजेता है;(function(){}());
रोको सी। बुल्जन

क्रॉकफ़ोर्ड वरीयता विवरण बहुत उपयोगी था - मैंने जंगली में देखे गए अंतरों की व्याख्या की है, जैसे कि jQuery के छोटे-पबसुब गिस्ट एक संस्करण से दूसरे संस्करण में स्विच किए गए हैं (आप फ़ाइल के अंत में परिवर्तन देख सकते हैं) और मैं नहीं कर सका ' पता नहीं क्यों।
ic9797

1
@Awesome_girl: ऐसा नहीं है कि एक ही चीज़ को लिखने के कई तरीके हैं; यह है कि JS में ऑपरेटरों के साथ एक ढीली प्रकार की प्रणाली है जो किसी भी मूल्य प्रकार पर काम कर सकता है। आप कर सकते हैं 1 - 1और आप आसानी से कर सकते हैं true - function(){}। यह केवल एक ही चीज़ है (एक इनफ़िक्स घटाव ऑपरेटर) लेकिन अलग-अलग, यहां तक ​​कि निरर्थक ऑपरेंड्स के साथ।

31

यह एक अनाम फ़ंक्शन घोषित करता है, फिर उसे कॉल करता है:

(function (local_arg) {
   // anonymous function
   console.log(local_arg);
})(arg);

मुझे लगता है कि "तर्क" बाहरी चर हैं जिन्हें फ़ंक्शन के भीतर स्थानीय संदर्भ में उपयोग किए जाने वाले "arg" के रूप में संदर्भित किया जाता है?
डालीबोर

@Dalibor argumentsहै विशेष ; मेरा अनुमान है कि जवाब देने वाला बस फ़्लिप करता है जहां नाम चलते हैं
बिल्ली

29

यह कह रहा है कि तुरंत निष्पादित करें।

तो अगर मैं:

var val = (function(){
     var a = 0;  // in the scope of this function
     return function(x){
         a += x;
         return a;
     };
})();

alert(val(10)); //10
alert(val(11)); //21

फिडल: http://jsfiddle.net/maniator/LqvpQ/


दूसरा उदाहरण:

var val = (function(){
     return 13 + 5;
})();

alert(val); //18

1
मुझे यह नहीं मिलता है कि यह अपने आप को साबित करने के लिए क्या करता है?
Exitos

1
@Exitos क्योंकि यह उस फ़ंक्शन को वापस करता है। बीमार एक दूसरा उदाहरण देते हैं।
नत्तली उर्फ ​​नील

बहुत आसान समझने के लिए +1
Adiii

24

उस निर्माण को तत्काल आमंत्रित समारोह अभिव्यक्ति (IIFE) कहा जाता है कहा जाता है जिसका अर्थ है कि इसे तुरंत निष्पादित किया जाता है। इसे एक फ़ंक्शन के रूप में सोचें जब दुभाषिया उस फ़ंक्शन तक पहुंच जाता है।

सबसे आम उपयोग के मामले:

इसके सबसे आम उपयोग मामलों में से एक के माध्यम से किए गए चर के दायरे को सीमित करना है var। चर के माध्यम से बनाए गए चर varएक फ़ंक्शन तक सीमित हैं, इसलिए यह निर्माण (जो कुछ कोड के आसपास एक फ़ंक्शन आवरण है) यह सुनिश्चित करेगा कि आपका चर दायरा उस फ़ंक्शन से लीक न हो।

निम्नलिखित उदाहरण में, countतुरंत लागू किए गए फ़ंक्शन के बाहर उपलब्ध नहीं होगा अर्थात फ़ंक्शन का दायरा countलीक से बाहर नहीं होगा। आप एक मिल जाना चाहिए ReferenceError, आप इसे वैसे भी तुरंत आह्वान समारोह के बाहर का उपयोग करने की कोशिश करनी चाहिए।

(function () { 
    var count = 10;
})();
console.log(count);  // Reference Error: count is not defined

ES6 वैकल्पिक (अनुशंसित)

ES6 में, हमारे पास अब वैरिएबल बनाए जा सकते हैं letऔर const। दोनों ब्लॉक-स्कोप्ड हैं (इसके विपरीत varजो फ़ंक्शन-स्कॉप्ड है)।

इसलिए, ऊपर उल्लिखित उपयोग के मामले के लिए IIFE के उस जटिल निर्माण का उपयोग करने के बजाय, आप अब यह सुनिश्चित करने के लिए बहुत सरल कोड लिख सकते हैं कि एक चर का दायरा आपके वांछित ब्लॉक से बाहर लीक नहीं करता है।

{ 
    let count = 10;
}
console.log(count);  // ReferenceError: count is not defined

इस उदाहरण में, हम चर letको परिभाषित करते थे countजो countकोड के ब्लॉक तक सीमित करता है , हमने घुंघराले कोष्ठक के साथ बनाया {...}

मैं इसे "कर्ली जेल" कहता हूं।


10
मुझे कर्ली जेल नामकरण पसंद है। शायद यह
चिपकेगा

15
(function () {
})();

इसे IIFE (तुरंत इनवॉइस फंक्शन एक्सप्रेशन) कहा जाता है। प्रसिद्ध जावास्क्रिप्ट डिजाइन पैटर्न में से एक, यह आधुनिक दिन के पैटर्न का दिल और आत्मा है। जैसा कि नाम से पता चलता है कि इसे बनाने के तुरंत बाद ही क्रियान्वित किया जाता है। यह पैटर्न निष्पादन की एक अलग या निजी गुंजाइश बनाता है।

ECMAScript 6 से पहले जावास्क्रिप्ट ने लेक्सिकल स्कूपिंग का उपयोग किया था, इसलिए ब्लॉक स्कोरिंग का अनुकरण करने के लिए IIFE का उपयोग किया गया था। (ECMAScript के साथ 6 ब्लॉक स्कूपिंग की शुरुआत letऔर constकीवर्ड के साथ संभव है ।) लेक्सिकल स्कूपिंग के साथ समस्या के लिए संदर्भ

IIFE के साथ ब्लॉक स्कूपिंग का अनुकरण करें

Iife के उपयोग करने का प्रदर्शन लाभ की तरह सामान्य रूप से प्रयुक्त वैश्विक वस्तुओं पारित करने की क्षमता है window, documentगुंजाइश देखने को कम करके एक तर्क के रूप, आदि। (याद रखें कि जावास्क्रिप्ट स्थानीय क्षेत्र में गुणों की तलाश करती है और वैश्विक दायरे तक श्रृंखला को आगे बढ़ाती है)। इसलिए स्थानीय दायरे में वैश्विक वस्तुओं तक पहुँचने के लिए नीचे दिए गए लुकअप समय को कम किया जाता है।

(function (globalObj) {
//Access the globalObj
})(window);

IIFE में दूसरे कोष्ठक को समझने के लिए जिस्ट प्रदान करने के लिए धन्यवाद। इसके अलावा परिभाषा में उन्हें परिभाषित करके वैश्विक चर के लुकअप समय लाभ को स्पष्ट करने के लिए
Arsal

11

नहीं, यह निर्माण केवल नामकरण की गुंजाइश बनाता है। यदि आप इसे भागों में तोड़ते हैं तो आप देख सकते हैं कि आपके पास एक बाहरी है

(...)();

यह एक फ़ंक्शन आह्वान है। आपके पास कोष्ठक के अंदर:

function() {}

यह एक अनाम फ़ंक्शन है। निर्माण के अंदर var के साथ घोषित किया गया सब कुछ केवल उसी निर्माण के अंदर दिखाई देगा और वैश्विक नाम स्थान को प्रदूषित नहीं करेगा।


11

यह जावास्क्रिप्ट में एक तुरंत आमंत्रित समारोह अभिव्यक्ति है:

जेएस में IIFE को समझने के लिए, इसे तोड़ना चाहिए:

  1. अभिव्यक्ति : कुछ जो एक मूल्य देता है
    उदाहरण: क्रोम कंसोल में निम्नलिखित का प्रयास करें। ये जेएस में भाव हैं।
a = 10 
output = 10 
(1+3) 
output = 4
  1. समारोह अभिव्यक्ति :
    उदाहरण:
// Function Expression 
var greet = function(name){
   return 'Namaste' + ' ' + name;
}

greet('Santosh');

फंक्शन एक्सप्रेशन कैसे काम करता है:
- जब JS इंजन पहली बार चलता है (Execution Context - Create Phase), तो यह फंक्शन (दाईं ओर = ऊपर) मेमोरी में निष्पादित या संग्रहीत नहीं होता है। परिवर्तनीय 'अभिवादन' को JS इंजन द्वारा 'अपरिभाषित' मान दिया गया है।
- निष्पादन के दौरान (एक्ज़िक्यूशन कॉन्टेक्ट - एक्ज़ीक्यूट फेज़), फ़्लायशन ऑब्जेक्ट फ़्लाई पर बनाया जाता है ( इसे अभी तक निष्पादित नहीं किया गया है ), 'शुभकामनाएँ' वेरिएबल को सौंपा जाता है और इसे 'ग्रीटिंग' ('सोमेनम') का उपयोग करते हुए लागू किया जा सकता है।

3. तुरंत आह्वान किया गया Funtion अभिव्यक्ति:

उदाहरण:

// IIFE
var greeting = function(name) {
    return 'Namaste' + ' ' + name;
}('Santosh')

console.log(greeting)  // Namaste Santosh. 

IIFE कैसे काम करता है :
- फ़ंक्शन की घोषणा के तुरंत बाद '()' को नोटिस करें। प्रत्येक फ़नक्शन ऑब्जेक्ट में एक 'CODE' गुण जुड़ा होता है जो कॉल करने योग्य होता है। और हम इसे '(') ब्रेसिज़ का उपयोग करके कॉल कर सकते हैं (या इसे लागू कर सकते हैं)।
- तो यहाँ, निष्पादन के दौरान (निष्पादन संदर्भ - निष्पादन चरण), फ़ंक्शन ऑब्जेक्ट बनाया जाता है और एक ही समय में इसका निष्पादन किया जाता है - इसलिए अब, ग्रीटिंग चर, funtion ऑब्जेक्ट होने के बजाय, इसका रिटर्न मान (एक स्ट्रिंग) है

जेएस में IIFE का विशिष्ट उपयोग:

निम्नलिखित IIFE पैटर्न आमतौर पर उपयोग किया जाता है।

// IIFE 
// Spelling of Function was not correct , result into error
(function (name) {
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');
  • हम यहाँ पर दो काम कर रहे हैं। a) ब्रेसेस के अंदर हमारे फंक्शन एक्सप्रेशन को रैप करना ()। यह सिंटैक्स पार्सर को यह बताने के लिए जाता है कि जो कुछ भी अंदर रखा गया है () इस मामले में एक अभिव्यक्ति (फ़ंक्शन अभिव्यक्ति) है और एक वैध कोड है।
    b) हम इसके अंत में () का उपयोग करके एक ही समय में इस funtion को लागू कर रहे हैं।

तो यह फ़ंक्शन उसी समय (IIFE) बनाया और निष्पादित किया जाता है।

IIFE के लिए महत्वपूर्ण usecase:

IIFE हमारे कोड को सुरक्षित रखता है।
- IIFE, एक फ़ंक्शन होने के नाते, इसका अपना निष्पादन संदर्भ है, जिसका अर्थ है कि इसके अंदर बनाए गए सभी चर इस फ़ंक्शन के लिए स्थानीय हैं और वैश्विक निष्पादन संदर्भ के साथ साझा नहीं किए गए हैं।

मान लीजिए कि मेरे आवेदन पत्र में एक और जेएस फाइल (test1.js) का उपयोग iife.js (नीचे देखें) के साथ किया गया है।

// test1.js

var greeting = 'Hello';

// iife.js
// Spelling of Function was not correct , result into error
(function (name) { 
   var greeting = 'Namaste';
   console.log(greeting + ' ' + name);
})('Santosh');

console.log(greeting)   // No collision happens here. It prints 'Hello'.

इसलिए IIFE हमें सुरक्षित कोड लिखने में मदद करता है जहां हम वैश्विक वस्तुओं के साथ अनायास नहीं टकरा रहे हैं।


अगर हम IIFE के अंदर फंक्शन्स बनाते हैं तो हम उन्हें कुछ अन्य js या jsx फाइल में कैसे एक्सेस कर सकते हैं यानी रिएक्शन कंपोनेंट में।
पत्थर की चट्टान

भले ही हमने IIFE का उपयोग नहीं किया, लेकिन ग्रीटिंग वैरिएबल ग्लोबल ग्रीटिंग वैरिएबल पर नहीं टकराएगा। तो वहाँ लाभ क्या है?
विली डेविड जूनियर

6

यह एक आत्म-आविष्कारक अनाम फ़ंक्शन है

एक स्व-चालान समारोह के W3Schools स्पष्टीकरण की जाँच करें ।

फ़ंक्शन अभिव्यक्तियों को "आत्म-आक्रमण" बनाया जा सकता है।

एक आत्म-आह्वान अभिव्यक्ति का आह्वान किया जाता है (शुरू), स्वचालित रूप से, बिना बुलाए।

यदि अभिव्यक्ति () द्वारा पीछा किया जाता है तो फंक्शन एक्सप्रेशन अपने आप निष्पादित हो जाएंगे।

आप एक फ़ंक्शन घोषणा को स्व-चालान नहीं कर सकते।


3
(function named(){console.log("Hello");}());<- फंक्शन नाम का सेल्फ
एक्जीक्यूटिंग

@bryc आप एक फ़ंक्शन का नाम क्यों देंगे, जिसे नाम की आवश्यकता नहीं है।
रिकार्डो गॉन्ज़ेल्स 3


5

यह स्व-अवलोकनीय अनाम फ़ंक्शन है। इसे परिभाषित करते समय इसे निष्पादित किया जाता है। जिसका अर्थ है कि यह फ़ंक्शन परिभाषित है और परिभाषा के तुरंत बाद ही आक्रमण करता है।

और वाक्य रचना की व्याख्या है: पहले ()कोष्ठक के भीतर का कार्य वह फ़ंक्शन है जिसका कोई नाम नहीं है और अगले ();कोष्ठक से आप समझ सकते हैं कि इसे उस समय परिभाषित किया गया है जब इसे परिभाषित किया गया है। और आप इस दूसरे ()कोष्ठक में किसी भी तर्क को पारित कर सकते हैं जिसे उस फ़ंक्शन में पकड़ा जाएगा जो पहले कोष्ठक में है। इस उदाहरण को देखें:

(function(obj){
    // Do something with this obj
})(object);

यहां आप जिस 'ऑब्जेक्ट' को पास कर रहे हैं, वह 'obj' द्वारा फंक्शन के भीतर पहुंचेगा, क्योंकि आप इसे फंक्शन सिग्नेचर में पकड़ रहे हैं।


2
इस प्रश्न का पहले से ही एक स्वीकृत उत्तर है और आपके उत्तर में ऐसा कुछ भी नहीं जोड़ा गया है जो पहले से स्वीकृत उत्तर द्वारा कवर नहीं किया गया है। इसलिए, इस उत्तर को लिखने की कोई आवश्यकता नहीं थी।
आदित एम शाह

3
मुझे कई उत्तरों को पढ़ना पसंद है, कभी-कभी एक या दूसरे के वाक्यांशों से फर्क पड़ता है।

मुझे लगा कि यह जोड़ा गया है क्योंकि इससे मुझे पता चलता है कि कोष्ठक का दूसरा सेट किस लिए था। कम से कम यहां यह स्पष्ट था कि मैंने देखा था।
जॉनी

मेरे fav ए.एस. IIFE के नमूने के दोनों सिरों में पैरामीटर हैं, और दोनों के बीच मैपिंग को सादा बनाया गया है।
स्टीफन डब्ल्यू राइट

4

यहाँ से प्रारंभ करें:

var b = 'bee';
console.log(b);  // global

इसे एक समारोह में रखें और यह अब वैश्विक नहीं है - आपका प्राथमिक लक्ष्य।

function a() {
  var b = 'bee';
  console.log(b);
}
a();
console.log(b);  // ReferenceError: b is not defined -- *as desired*

फ़ंक्शन को तुरंत कॉल करें - उफ़:

function a() {
  var b = 'bee';
  console.log(b);
}();             // SyntaxError: Expected () to start arrow function, but got ';' instead of '=>'

सिंटैक्स त्रुटि से बचने के लिए कोष्ठकों का उपयोग करें:

(function a() {
  var b = 'bee';
  console.log(b);
})(); // OK now

आप फ़ंक्शन का नाम छोड़ सकते हैं:

(function () {    // no name required
  var b = 'bee';
  console.log(b);
})();

यह उससे अधिक जटिल होने की आवश्यकता नहीं है।


2
सिंटैक्स त्रुटि तीर फ़ंक्शन के बारे में बात कर रही है। जैसा कि मैं समझता हूं, यह js की एक नई विशेषता है, और यह कुछ साल पहले मौजूद नहीं था, लेकिन IIFE ने किया। तो, कोष्ठक शायद मूल रूप से एक वाक्यविन्यास त्रुटि से बचने के लिए इस्तेमाल किया गया था, लेकिन एक अलग?
JCarlosR

क्या आप कृपया @Jarlos सवाल का जवाब दे सकते हैं? जैसा कि वह काफी सही ढंग से बताते हैं कि तीर के कार्य से पहले IIFE बहुत कुछ आया था, यह समझने में मदद करेगा कि लपेटने की आवश्यकता क्यों है।
स्क्रिप्ट 47

@ Script47 के पास टिप्पणी में JCarlos के प्रश्न का उत्तर नहीं है। आप एक नया प्रश्न बना सकते हैं और इसे पोस्ट कर सकते हैं, और मुझे यकीन है कि आपको कुछ अच्छे उत्तर मिलेंगे।
जिम फ्लड

@JCarlos जब मैं उस एरर को अंजाम देता हूं जो एरर फेंकता है, तो मैं वास्तव Uncaught SyntaxError: Unexpected token )में एरो फंक्शन के किसी भी उल्लेख के बजाय मिलता हूं । क्या आप संभवतः तीर फ़ंक्शन फ़ंक्शन को फेंकने के साथ एक बेला साझा कर सकते हैं?
स्क्रिप्ट 47

2

स्वयं-निष्पादित अनाम फ़ंक्शन। जैसे ही इसे बनाया जाता है इसे निष्पादित किया जाता है।

एक छोटा और डमी उदाहरण जहां यह उपयोगी है:

function prepareList(el){
  var list = (function(){
    var l = []; 
    for(var i = 0; i < 9; i++){
     l.push(i);
    }
    return l;
  })();

  return function (el){
    for(var i = 0, l = list.length; i < l; i++){
      if(list[i] == el) return list[i];
    }
    return null;
  }; 
} 

var search = prepareList();
search(2);
search(3);

इसलिए हर बार सूची बनाने के बजाय, आप इसे केवल एक बार (कम ओवरहेड) बनाते हैं।


1
जैसा कि लिखा गया है, आपकी खोज प्रत्येक आह्वान पर सूची का पुनर्निर्माण करती है। उससे बचने के लिए, आपको (1) सूची बनाने की जरूरत है और (2) खोज फ़ंक्शन को एक क्लोजर के रूप में वापस लौटाएं जो आपके द्वारा बनाई गई सूची तक पहुंच है। यह आप गुमनाम सेल्फ-इनवॉइसिंग फॉर्म का उपयोग करके आसानी से कर सकते हैं। Jsfiddle.net/BV4bT देखें ।
जॉर्ज

क्या आप समझा सकते हैं ... कम ओवरहेड .. मैं इस भाग को नहीं समझ सकता
HIRA THAKUR

2
ओवरहेड का अर्थ है कोई भी कार्य जो आवश्यक नहीं है। प्रत्येक फ़ंक्शन के आह्वान पर एक सरणी को पॉप्युलेट करना आवश्यक नहीं है, यही कारण है कि उदाहरण में एक सरणी आत्म-निष्पादन द्वारा आबादी है। केवल पहली बार अनाम फ़ंक्शन। हालांकि, ऐसा लगता है कि मैंने अपने जवाब में गलती की है, जॉर्ज की टिप्पणी में एक उचित उदाहरण के लिए लिंक देखें।
usoban

2

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

कोड

var same_name = 1;

var myVar = (function() {
    var same_name = 2;
    console.log(same_name);
})();

console.log(same_name);

इस उत्पादन का उत्पादन:

2
1

इस सिंटैक्स का उपयोग करके आप अपने जावास्क्रिप्ट कोड में कहीं और घोषित किए गए वैश्विक चर से टकराने से बचते हैं।


1
सही, आउटपुट 2 और फिर 1 होगा क्योंकि myVar को पहले चलाया जाएगा
Dalibor

1
आपकी व्याख्या फंक्शन स्कोप की व्याख्या करने में अच्छा करती है लेकिन यह समझाने में कम पड़ जाती है कि इसे तुरंत क्यों निष्पादित किया गया। इसे एक चर को सौंपना आत्म पराजित है और यह भी इरादा कर सकता है कि इसे एक से अधिक बार निष्पादित किया जा सकता है। var same_name = 1; var myVar = function() { var same_name = 2; console.log(same_name); }; myVar(); console.log(same_name); एक ही परिणाम होगा।
15:25 पर domenicr

2

इसे IIFE कहा जाता है - तुरंत इनवॉइस फंक्शन एक्सप्रेशन। यह सिंटैक्स और उपयोग दिखाने के लिए एक उदाहरण है। इसका उपयोग केवल फ़ंक्शन तक वेरिएबल के उपयोग को स्कोप करने के लिए किया जाता है और इससे परे नहीं।

(function () {
  function Question(q,a,c) {
    this.q = q;
    this.a = a;
    this.c = c;
  }

  Question.prototype.displayQuestion = function() {
    console.log(this.q);
    for (var i = 0; i < this.a.length; i++) {
      console.log(i+": "+this.a[i]);
    }
  }

  Question.prototype.checkAnswer = function(ans) {
    if (ans===this.c) {
      console.log("correct");
    } else {
      console.log("incorrect");
    }
  }

  var q1 = new Question('Is Javascript the coolest?', ['yes', 'no'], 0);
  var q2 = new Question('Is python better than Javascript?', ['yes', 'no', 'both are same'], 2);
  var q3 = new Question('Is Javascript the worst?', ['yes', 'no'], 1);

  var questions = [q1, q2, q3];

  var n = Math.floor(Math.random() * questions.length)

  var answer = parseInt(prompt(questions[n].displayQuestion()));
  questions[n].checkAnswer(answer);
})();

1

IIFE (तुरंत फ़ंक्शन फ़ंक्शन को आमंत्रित किया जाता है) एक फ़ंक्शन है जो स्क्रिप्ट लोड होते ही निष्पादित होता है और चला जाता है।

Iife.js नामक फाइल में नीचे दिए गए फ़ंक्शन पर विचार करें

(function(){
       console.log("Hello Stackoverflow!");
   })();

जैसे ही आप iife.js को लोड करेंगे, ऊपर का यह कोड निष्पादित हो जाएगा और ' Hello Stackoverflow ' को प्रिंट कर देगा ! 'डेवलपर टूल' कंसोल पर।

विस्तृत विवरण के लिए, तत्काल-इनवॉइस फंक्शन एक्सप्रेशन (IIFE) देखें


1

एक और उपयोग मामला संस्मरण है जहां कैश ऑब्जेक्ट वैश्विक नहीं है:

var calculate = (function() {
  var cache = {};
  return function(a) {

    if (cache[a]) {
      return cache[a];
    } else {
      // Calculate heavy operation
      cache[a] = heavyOperation(a);
      return cache[a];
    }
  }
})();

0

एक तुरंत आह्वान समारोह अभिव्यक्ति (IIFE) एक ऐसा कार्य है जो इसे बनाते ही निष्पादित हो जाता है। इसका किसी भी घटना या अतुल्यकालिक निष्पादन से कोई संबंध नहीं है। आप नीचे दिखाए गए अनुसार IIFE को परिभाषित कर सकते हैं:

(function() {
     // all your code here
     // ...
})();

कोष्ठक समारोह की पहली जोड़ी () {...} कोष्ठक के अंदर कोड को एक अभिव्यक्ति में परिवर्तित करता है। दूसरी जोड़ी कोष्ठक अभिव्यक्ति के फलस्वरूप होने वाले कार्य को कहता है।

एक IIFEको स्व-आहरण अनाम फ़ंक्शन के रूप में भी वर्णित किया जा सकता है। इसका सबसे सामान्य उपयोग नाम टक्करों से बचने के लिए var के माध्यम से बने चर के दायरे को सीमित करना या संदर्भ को संक्षिप्त करना है।


0

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

दूसरे शब्दों में, वे प्रोग्राम की तरह होते हैं जो प्रोग्राम की शुरुआत में "कक्षाएं बनाते हैं"। उनके तुरंत बाद (स्वचालित रूप से) होने के बाद, केवल वही फ़ंक्शन उपलब्ध हैं जो अनाम फ़ंक्शन द्वारा दिए गए हैं। हालांकि, अन्य सभी '। छिपी हुई 'फ़ंक्शंस अभी भी हैं, किसी भी राज्य के साथ (स्कोप निर्माण के दौरान सेट किए गए चर)।

बहुत ही शांत।


0

निम्नलिखित कोड:

(function () {

})();

एक तुरंत आह्वान समारोह अभिव्यक्ति (IIFE) कहा जाता है ।

इसे एक फ़ंक्शन अभिव्यक्ति कहा जाता है क्योंकि ( yourcode )जावास्क्रिप्ट में ऑपरेटर इसे एक अभिव्यक्ति में मजबूर करता है। एक फ़ंक्शन अभिव्यक्ति और एक फ़ंक्शन घोषणा के बीच का अंतर निम्नलिखित है:

// declaration:
function declaredFunction () {}

// expressions:

// storing function into variable
const expressedFunction = function () {}

// Using () operator, which transforms the function into an expression
(function () {})

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

हमारे पास एक अभिव्यक्ति है जो एक फ़ंक्शन ऑब्जेक्ट का मूल्यांकन करता है जिसके बाद हम तुरंत ऑपरेटर के साथ फ़ंक्शन ऑब्जेक्ट को लागू कर सकते हैं ()। उदाहरण के लिए:

(function() {

  const foo = 10;        // all variables inside here are scoped to the function block
  console.log(foo);

})();

console.log(foo);  // referenceError foo is scoped to the IIFE

यह क्यों उपयोगी है?

जब हम एक बड़े कोड बेस के साथ काम कर रहे हैं और / या जब हम विभिन्न पुस्तकालयों का आयात कर रहे हैं तो नामकरण संघर्ष की संभावना बढ़ जाती है। जब हम अपने कोड के कुछ हिस्सों को लिख रहे होते हैं जो एक IIFE के अंदर संबंधित (और इस तरह एक ही चर का उपयोग कर रहा है) सभी चर और फ़ंक्शन नाम IIFE के फ़ंक्शन कोष्ठक में स्कोप किए जाते हैं । इससे संघर्षों के नामकरण की संभावना कम हो जाती है और आप उन्हें अधिक लापरवाह नाम देते हैं (जैसे कि आपको उन्हें उपसर्ग करने की आवश्यकता नहीं है)।


0

ईएस 6 सिंटैक्स में (स्वयं के लिए पोस्टिंग, जैसा कि मैं इस पृष्ठ पर त्वरित उदाहरण की तलाश में रहता हूं):

// simple
const simpleNumber = (() => {
  return true ? 1 : 2
})()

// with param
const isPositiveNumber = ((number) => {
  return number > 0 ? true : false
})(4)

0

इस फंक्शन को सेल्फ इनवॉइसिंग फंक्शन कहा जाता है। एक आत्म-आह्वान (जिसे स्व-क्रियान्वयन भी कहा जाता है) फ़ंक्शन एक नामांकित (अनाम) फ़ंक्शन है जिसे इसकी परिभाषा के तुरंत बाद कॉल किया जाता है (कॉल किया जाता है)।यहाँ और पढ़ें

ये फ़ंक्शन क्या करते हैं, जब फ़ंक्शन को परिभाषित किया जाता है, तो फ़ंक्शन तुरंत कहा जाता है, जो कोड के समय और अतिरिक्त लाइनों को बचाता है (जैसा कि इसे अलग लाइन पर कॉल करने की तुलना में)।

यहाँ एक उदाहरण है:

(function() {
    var x = 5 + 4;
    console.log(x);
})();


0

यह इस बात की गहराई से व्याख्या है कि आप इसका उपयोग क्यों करेंगे:

"IIFE का उपयोग करने का प्राथमिक कारण डेटा गोपनीयता प्राप्त करना है। क्योंकि जावास्क्रिप्ट का संस्करण उनके कार्य करने के लिए चर बनाता है, IIFE के भीतर घोषित किसी भी चर को बाहरी दुनिया द्वारा एक्सेस नहीं किया जा सकता है।"

http://adripofjavascript.com/blog/drips/an-introduction-to-iffes-immediately-invoked-function-expressions.html


0

यह एक फंक्शन एक्सप्रेशन है, यह तुरंत इन्वॉल्व्ड फंक्शन एक्सप्रेशन (IIFE) के लिए है। IIFE बस एक ऐसा फंक्शन है जिसे बनाने के ठीक बाद निष्पादित किया जाता है। तो जब तक इसे निष्पादित करने के लिए नहीं कहा जाता है, तब तक प्रतीक्षा करने के लिए समारोह के आईआईएफई को तुरंत निष्पादित किया जाता है। आइए उदाहरण के लिए IIFE का निर्माण करें। मान लें कि हमारे पास एक ऐड फंक्शन है जो दो पूर्णांक को आर्ग के रूप में लेता है और योग देता है जो ऐड फ़ंक्शन को IIFE में बनाता है,

चरण 1: फ़ंक्शन को परिभाषित करें

function add (a, b){
    return a+b;
}
add(5,5);

Step2: पूरे फंक्शनल डिक्लेरेशन को कोष्ठकों में लपेटकर फ़ंक्शन को कॉल करें

(function add (a, b){
    return a+b;
})
//add(5,5);

चरण 3: फ़ंक्शन को लागू करने के लिए तुरंत कॉल से 'जोड़ें' पाठ को हटा दें।

(function add (a, b){
    return a+b;
})(5,5);

IFFE का उपयोग करने का मुख्य कारण आपके फ़ंक्शन के भीतर एक निजी गुंजाइश को संरक्षित करना है। अपने जावास्क्रिप्ट कोड के अंदर आप यह सुनिश्चित करना चाहते हैं कि, आप किसी भी वैश्विक चर को ओवरराइड नहीं कर रहे हैं। कभी-कभी आप आकस्मिक रूप से एक वैरिएबल को परिभाषित कर सकते हैं जो वैश्विक वैरिएबल को ओवरराइड करता है। आइए उदाहरण के द्वारा प्रयास करें। मान लें कि हमारे पास iffe.html नामक एक html फ़ाइल है और बॉडी टैग के अंदर कोड हैं-

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

ठीक है, उपरोक्त कोड किसी भी प्रश्न के साथ निष्पादित करेगा, अब मान लें कि आप एक चर नाम का दस्तावेज आकस्मिक या जानबूझकर घोषित करते हैं।

<body>
    <div id = 'demo'></div>
    <script>
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
        const document = "hi there";
        console.log(document);
    </script> 
</body>

आप एक SyntaxError में एंडअप करेंगे : गैर-विन्यास योग्य वैश्विक संपत्ति दस्तावेज़ का पुनर्वितरण।

लेकिन अगर आपकी इच्छा एक चर नाम documet घोषित करने की है, तो आप इसे IFFE का उपयोग करके कर सकते हैं।

<body>
    <div id = 'demo'></div>
    <script>
        (function(){
            const document = "hi there";
            this.document.getElementById("demo").innerHTML = "Hello JavaScript!";
            console.log(document);
        })();
        document.getElementById("demo").innerHTML = "Hello JavaScript!";
    </script> 
</body>

आउटपुट:

यहां छवि विवरण दर्ज करें

आइए एक और उदाहरण द्वारा कोशिश करते हैं, मान लें कि हमारे पास कैलकुलेटर जैसी कोई वस्तु है-

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
    </script> 
</body>

वैसे यह एक आकर्षण की तरह काम कर रहा है, क्या होगा अगर हम गलती से कैलकुलेटर ऑब्जेक्ट के मूल्य को फिर से असाइन करें।

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        console.log(calculator.add(5,10));
        calculator = "scientific calculator";
        console.log(calculator.mul(5,5));
    </script> 
</body>

हाँ, आप एक TypeError के साथ एंडअप करेंगे: कैलकुलेटर ।.m एक फ़ंक्शन iffe.html नहीं है

लेकिन IFFE की मदद से हम एक निजी दायरा बना सकते हैं जहाँ हम एक और परिवर्तनशील नाम कैलकुलेटर बना सकते हैं और उसका उपयोग कर सकते हैं;

<body>
    <script>
        var calculator = {
            add:function(a,b){
                return a+b;
            },
            mul:function(a,b){
                return a*b;
            }
        }
        var cal = (function(){
            var calculator = {
                sub:function(a,b){
                    return a-b;
                },
                div:function(a,b){
                    return a/b;
                }
            }
            console.log(this.calculator.mul(5,10));
            console.log(calculator.sub(10,5));
            return calculator;
        })();
        console.log(calculator.add(5,10));
        console.log(cal.div(10,5));
    </script> 
</body>

आउटपुट: यहां छवि विवरण दर्ज करें


-1

मुझे लगता है कि कोष्ठक के 2 सेट इसे थोड़ा भ्रमित करते हैं लेकिन मैंने googles उदाहरण में एक और उपयोग देखा, उन्होंने कुछ इसी तरह का उपयोग किया, मुझे आशा है कि यह आपको बेहतर समझने में मदद करेगा:

var app = window.app || (window.app = {});
console.log(app);
console.log(window.app);

इसलिए यदि windows.appपरिभाषित नहीं किया गया है, तो window.app = {}तुरंत निष्पादित किया जाता है, इसलिए स्थिति मूल्यांकन के दौरान window.appसौंपा गया है {}, इसलिए परिणाम दोनों appऔर window.appअब बन गए हैं {}, इसलिए कंसोल आउटपुट है:

Object {}
Object {}

-1

आमतौर पर, हम प्रोग्राम में लिखने के तुरंत बाद एक फंक्शन नहीं करते हैं। अत्यंत सरल शब्दों में, जब आप इसके निर्माण के ठीक बाद एक फ़ंक्शन कहते हैं, तो इसे IIFE कहा जाता है - एक फैंसी नाम।


-1

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

दो तरीकों से हम IIFE बना सकते हैं

(function () {
    "use strict";
    var app = angular.module("myModule", []);
}());

या

(function () {
    "use strict";
    var app = angular.module("myModule", []);
})();

ऊपर दिए गए कोड स्निपेट में, " var app " अब एक स्थानीय चर है।

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