2012-01-29 22 views
97

संभव डुप्लिकेट:
What is the (function() { })() construct in JavaScript?उन्नत जावास्क्रिप्ट: यह फ़ंक्शन कोष्ठक में क्यों लपेटा गया है?

मैं जावा स्क्रिप्ट कोड के इस बिट भर में आया है, लेकिन मुझे नहीं पता कि क्या इसे से बाहर करना है। जब मैं इस कोड को चलाता हूं तो मुझे "1" क्यों मिलता है? (1) का यह अजीब छोटा परिशिष्ट क्या है और फ़ंक्शन कोष्ठक में क्यों लपेटा गया है?

(function(x){ 
    delete x; 
    return x; 
})(1); 
+0

यह एक आईआईएफई है, यहां विवरण: http://www.markupjavascript.com/2016/07/what-are-immediately-invoked-function.html –

उत्तर

208

यहां कुछ चीजें चल रही हैं।

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

यह अपने स्वयं के दायरे में कुछ जावास्क्रिप्ट कोड निष्पादित करने के लिए एक तरीका प्रदान करता है: पहले immediately invoked function expression (Iife) पैटर्न है। आमतौर पर इसका उपयोग किया जाता है ताकि फ़ंक्शन के भीतर बनाए गए किसी भी चर वैश्विक स्तर को प्रभावित न करें। आप इसके बजाय इसका उपयोग कर सकते हैं:

function foo() { 
    // Some code 
} 
foo(); 

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

इस सिंटैक्स अमान्य है:

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

क्योंकि आप यह अभिव्यक्ति के रूप में पार्स करने के लिए कोष्ठक में समारोह रैप करने के लिए किया है। और जानकारी यहां है: अपने स्वयं के दायरे के भीतर

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

की अनुमति देता है 'कुछ कोड' तुरंत निष्पादित किया जाना है, जैसे कि यह सिर्फ इनलाइन लिखा गया था, लेकिन यह भी: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

तो Iife तर्ज पर जल्दी से संक्षेप में ताकि ग्लोबल नेमस्पेस को प्रभावित न किया जा सके (और इस प्रकार अन्य स्क्रिप्ट्स द्वारा संभावित रूप से हस्तक्षेप या हस्तक्षेप किया जा सके)।

तुम बस के रूप में अपने कार्य करने के लिए तर्क पारित कर सकते हैं आप एक सामान्य कार्य, उदाहरण के लिए,

(function(x) { 
    // Some code 
})(1); 

तो हम समारोह के लिए पहला तर्क है, जो इसे प्राप्त करता है के रूप में मूल्य गुजर रहे हैं '1' एक स्थानीय रूप से स्कॉप्ड चर के रूप में, नाम एक्स।

delete x; 
return x; 

हटाने ऑपरेटर वस्तुओं से गुण निकाल देगा:

दूसरे, आप समारोह कोड के ही हिम्मत की है। यह चर हटा नहीं है। इसलिए;

इस में
var foo = {'bar':4, 'baz':5}; 
delete foo.bar; 
console.log(foo); 

परिणाम लॉग किया जा रहा:

{'baz':5} 

जबकि,

var foo = 4; 
delete foo; 
console.log(foo); 

मूल्य 4 प्रवेश करेंगे, क्योंकि foo एक चर नहीं एक संपत्ति है और इसलिए यह नहीं किया जा सकता नष्ट कर दिया।

कई लोग मानते हैं कि हटाना वैरिएबल को हटा सकता है, जिस तरह से ऑटोग्लोबल्स काम करते हैं। ,

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this! 
delete bar; 
console.log(bar); // Error - bar is not defined. 

इस बार हटाने का काम करता है, क्योंकि आप एक चर को हटाने नहीं कर रहे हैं, लेकिन: आप इसे पहले की घोषणा के बिना एक चर को असाइन करते हैं, यह वास्तव में एक चर, लेकिन वैश्विक वस्तु पर एक संपत्ति बन नहीं होगा वैश्विक वस्तु पर एक संपत्ति। वास्तव में, पिछले टुकड़ा इस के बराबर है:

window.bar = 4; 
delete window.bar; 
console.log(window.bar); 

और अब आप देख सकते हैं कि यह foo वस्तु उदाहरण और नहीं foo चर उदाहरण के अनुरूप है।

+18

बहुत अच्छी व्याख्या! –

+1

बहुत अच्छी तरह से व्याख्या स्पष्टीकरण। साथ ही, एक साइड-नोट के रूप में, मैंने डगलस क्रॉकफोर्ड को एक ऐसी बातचीत में उल्लेख किया जो वह पसंद करता है (फ़ंक्शन() {}()); स्पष्ट रूप से स्पष्ट रूप से माता-पिता में पूरे आईआईएफई को लपेटना - अधिक अभिव्यक्तिपूर्ण। विकी लिंक की तुलना में – GuiDoody

+0

, माता-पिता पूरी चीज लपेट रहे हैं, क्या इससे कोई अंतर आता है? –

9

इसका मतलब है कि आप एक गुमनाम समारोह बनाया है, और पैरामीटर 1 से कॉल करने की।

यह सिर्फ रूप में ही है:

function foo(x) { 
    delete x; 
    return x; 
} 
foo(1); 
+2

मैं एक 'var foo = function() {} का उपयोग करूंगा भ्रमित फ़ंक्शन स्टेटमेंट्स और फ़ंक्शन एक्सप्रेशन से बचें। – hugomg

+1

@missingno वे वही हैं। – xdazz

1

कारण यह है कि आप अभी भी मिलता है 1 लौटे कि हटाने कीवर्ड वस्तुओं के गुणों को दूर करने के लिए है। शेष है जैसे कि अन्य ने टिप्पणी की है, ब्रैकेट में लिपटे कुछ भी एक समारोह के रूप में निष्पादित होता है, और ब्रैकेट का दूसरा सेट उस ब्लॉक को पारित तर्क हैं।

यहां MDN reference for delete और MDN reference for closures है, जो अज्ञात कार्यों पर भी चर्चा करता है।

2

लोग आम तौर पर इन "तुरंत आमंत्रित फ़ंक्शन अभिव्यक्तियों" या "स्वयं निष्पादन कार्य" कहते हैं।

ऐसा करने का बिंदु यह है कि उस फ़ंक्शन के अंदर घोषित चर को बाहरी रूप से रिसाव नहीं किया जाता है।