(function() {})()और इसके jQuery के विशिष्ट चचेरे भाई (function($) {})(jQuery)जावास्क्रिप्ट कोड में हर समय पॉप अप करते हैं।
ये निर्माण कैसे काम करते हैं, और वे किन समस्याओं का समाधान करते हैं?
उदाहरणों की सराहना की
(function() {})()और इसके jQuery के विशिष्ट चचेरे भाई (function($) {})(jQuery)जावास्क्रिप्ट कोड में हर समय पॉप अप करते हैं।
ये निर्माण कैसे काम करते हैं, और वे किन समस्याओं का समाधान करते हैं?
उदाहरणों की सराहना की
jQuery तर्क के रूप में करता है।
जवाबों:
जावास्क्रिप्ट फ्रेमवर्क की बढ़ती लोकप्रियता के साथ, $कई अलग-अलग अवसरों में संकेत का उपयोग किया गया था। तो, संभावित झड़पों को कम करने के लिए, आप उन निर्माणों का उपयोग कर सकते हैं:
(function ($){
// Your code using $ here.
})(jQuery);
विशेष रूप से, यह एक अनाम फ़ंक्शन घोषणा है जो पैरामीटर के रूप में तुरंत मुख्य jQuery ऑब्जेक्ट को पारित करने के लिए निष्पादित होती है । उस फ़ंक्शन के अंदर, आप $उस ऑब्जेक्ट को संदर्भित करने के लिए उपयोग कर सकते हैं , अन्य चौखटों के बारे में भी चिंता किए बिना।
यह एक ऐसी तकनीक है जिसका उपयोग चर क्षेत्र को सीमित करने के लिए किया जाता है; यह वैरिएबल को वैश्विक नाम स्थान को प्रदूषित करने से रोकने का एकमात्र तरीका है।
var bar = 1; // bar is now part of the global namespace
alert(bar);
(function () {
var foo = 1; // foo has function scope
alert(foo);
// code to be executed goes here
})();
1) यह एक अनाम फ़ंक्शन को परिभाषित करता है और इसे सीधे निष्पादित करता है।
2) यह आमतौर पर अवांछित कोड के साथ वैश्विक नाम स्थान को प्रदूषित नहीं करने के लिए किया जाता है।
3) आपको इससे कुछ तरीकों को उजागर करने की आवश्यकता है, अंदर घोषित कुछ भी "निजी" होगा, उदाहरण के लिए:
MyLib = (function(){
// other private stuff here
return {
init: function(){
}
};
})();
या, वैकल्पिक रूप से:
MyLib = {};
(function({
MyLib.foo = function(){
}
}));
मुद्दा यह है कि आप इसका उपयोग करने के कई तरीके हैं, लेकिन परिणाम वही रहता है।
यह सिर्फ एक अनाम फ़ंक्शन है जिसे तुरंत कहा जाता है। आप पहले फ़ंक्शन बना सकते हैं और फिर उसे कॉल कर सकते हैं, और आपको समान प्रभाव मिलेगा:
(function(){ ... })();
के रूप में काम करता है:
temp = function(){ ... };
temp();
आप एक नामित फ़ंक्शन के साथ भी ऐसा कर सकते हैं:
function temp() { ... }
temp();
कोड जिसे आप jQuery- विशिष्ट कहते हैं, केवल इस अर्थ में है कि आप इसमें jQuery ऑब्जेक्ट का उपयोग करते हैं। यह एक पैरामीटर के साथ सिर्फ एक अनाम फ़ंक्शन है, जिसे तुरंत कहा जाता है।
आप दो चरणों में एक ही काम कर सकते हैं, और आप इसे किसी भी पैरामीटर के साथ कर सकते हैं जो आपको पसंद है:
temp = function(answer){ ... };
temp(42);
समस्या यह है कि यह हल करती है कि यह फ़ंक्शन में कोड के लिए एक क्लोज़्यूज़ बनाता है। आप वैश्विक नाम स्थान को प्रदूषित किए बिना इसमें चर घोषित कर सकते हैं, इस प्रकार एक स्क्रिप्ट को दूसरे के साथ प्रयोग करते समय टकराव के जोखिम को कम कर सकते हैं।
JQuery के लिए विशिष्ट मामले में आप इसे संगतता मोड में उपयोग करते हैं जहां यह jQuery के लिए उपनाम के रूप में $ $ की घोषणा नहीं करता है। JQuery ऑब्जेक्ट को क्लोजर में भेजने और पैरामीटर $ का नामकरण करके आप अभी भी संगतता मोड के बिना समान सिंटैक्स का उपयोग कर सकते हैं।
यह यहाँ बताता है कि आपका पहला निर्माण चरों के लिए गुंजाइश प्रदान करता है।
जावास्क्रिप्ट में फंक्शन लेवल पर वेरिएबल्स को स्कैन किया जाता है। यह आपके लिए C # या जावा जैसी भाषा में उपयोग किया जा सकता है, जहां चर खंड में ब्लॉक किए गए हैं। इसका मतलब क्या है यदि आप एक लूप के अंदर एक चर घोषित करते हैं या यदि एक बयान है, तो यह पूरे फ़ंक्शन के लिए उपलब्ध होगा।
यदि आप कभी भी अपने आप को एक फ़ंक्शन के अंदर एक चर को स्पष्ट रूप से गुंजाइश करने की आवश्यकता पाते हैं तो आप ऐसा करने के लिए एक अनाम फ़ंक्शन का उपयोग कर सकते हैं। आप वास्तव में एक अनाम फ़ंक्शन बना सकते हैं और फिर उसे सीधे निष्पादित कर सकते हैं और अंदर के सभी चर अनाम फ़ंक्शन पर स्कोप किए जाएंगे:
(function() {
var myProperty = "hello world";
alert(myProperty);
})();
alert(typeof(myProperty)); // undefined
ऐसा करने का एक अन्य कारण यह है कि $आप किस फ्रेमवर्क के ऑपरेटर का उपयोग कर रहे हैं, इस पर कोई भ्रम दूर करना है। उदाहरण के लिए, jQuery को बाध्य करने के लिए, आप यह कर सकते हैं:
;(function($){
... your jQuery code here...
})(jQuery);
$ऑपरेटर के रूप में एक पैरामीटर के रूप में गुजरने और इसे jQuery पर लागू करने से, $फ़ंक्शन के भीतर का ऑपरेटर jQuery के लिए लॉक हो जाता है, भले ही आपके पास अन्य फ्रेमवर्क लोड हो।
इस निर्माण के लिए एक और उपयोग स्थानीय चर के मूल्यों को "कैप्चर" करना है जो एक क्लोजर में उपयोग किया जाएगा। उदाहरण के लिए:
for (var i = 0; i < 3; i++) {
$("#button"+i).click(function() {
alert(i);
});
}
उपरोक्त कोड तीनों बटन "3" को पॉप अप कर देगा। दूसरी ओर:
for (var i = 0; i < 3; i++) {
(function(i) {
$("#button"+i).click(function() {
alert(i);
});
})(i);
}
यह तीन बटन "0", "1", और "2" को अपेक्षित रूप से पॉप अप करेगा।
इसका कारण यह है कि एक बंद अपने संलग्नक स्टैक फ्रेम का संदर्भ रखता है , जो इसके चर के मौजूदा मूल्यों को रखता है। यदि क्लोजर निष्पादित होने से पहले वे चर बदल जाते हैं, तो क्लोजर केवल नवीनतम मानों को देखेगा, न कि उन मानों को, जैसा कि उस समय था जब क्लोजर बनाया गया था। ऊपर के दूसरे उदाहरण के रूप में किसी अन्य फ़ंक्शन के अंदर क्लोजर निर्माण को लपेटकर i, अनाम फ़ंक्शन के स्टैक फ्रेम में चर के वर्तमान मूल्य को बचाया जाता है।
यह एक बंद माना जाता है । इसका अर्थ है कि समाहित कोड अपने ही शाब्दिक दायरे के भीतर चलेगा। इसका मतलब है कि आप नए चर और कार्यों को परिभाषित कर सकते हैं और वे बंद के बाहर कोड में उपयोग किए गए नाम स्थान से नहीं टकराएंगे।
var i = 0;
alert("The magic number is " + i);
(function() {
var i = 99;
alert("The magic number inside the closure is " + i);
})();
alert("The magic number is still " + i);
यह तीन पॉपअप उत्पन्न करेगा, यह दर्शाता है कि iक्लोजर समान नाम के पहले से मौजूद चर को नहीं बदलता है:
वे अक्सर jQuery प्लगइन्स में उपयोग किया जाता है। जैसा कि jQuery प्लगइन्स ऑथरिंग गाइड में बताया गया है कि अंदर घोषित सभी वैरिएबल { }निजी हैं और बाहर से दिखाई नहीं देते हैं जो बेहतर एनकैप्सुलेशन की अनुमति देता है।
{}अपने आप में नहीं और जावास्क्रिप्ट में एक नया दायरा बनाएँ। कार्यक्षेत्र घोषणा द्वारा बनाया गया है।
जैसा कि दूसरों ने कहा है, वे दोनों उन अनाम कार्यों को परिभाषित करते हैं जो तुरंत लागू होते हैं। मैं आम तौर पर इस संरचना में अपने जावास्क्रिप्ट वर्ग घोषणाओं को लपेटता हूं ताकि कक्षा के लिए एक स्थिर निजी गुंजाइश बनाई जा सके। मैं तब लगातार डेटा, स्थिर विधियों, घटना संचालकों, या उस दायरे में और कुछ भी रख सकता हूं और यह केवल कक्षा के उदाहरणों के लिए दिखाई देगा:
// Declare a namespace object.
window.MyLibrary = {};
// Wrap class declaration to create a private static scope.
(function() {
var incrementingID = 0;
function somePrivateStaticMethod() {
// ...
}
// Declare the MyObject class under the MyLibrary namespace.
MyLibrary.MyObject = function() {
this.id = incrementingID++;
};
// ...MyObject's prototype declaration goes here, etc...
MyLibrary.MyObject.prototype = {
memberMethod: function() {
// Do some stuff
// Maybe call a static private method!
somePrivateStaticMethod();
}
};
})();
इस उदाहरण में, MyObjectवर्ग MyLibraryनाम स्थान को सौंपा गया है, इसलिए यह सुलभ है। incrementingIDऔर somePrivateStaticMethod()अनाम फ़ंक्शन दायरे के बाहर सीधे पहुंच योग्य नहीं हैं।
यह मूल रूप से आपके जावास्क्रिप्ट कोड को नाम स्थान देने के लिए है।
उदाहरण के लिए, आप किसी भी चर या कार्य को वहां और बाहर से रख सकते हैं, वे उस दायरे में मौजूद नहीं हैं। इसलिए जब आप सब कुछ वहाँ करते हैं, तो आपको झड़पों के बारे में चिंता करने की ज़रूरत नहीं है।
()स्वयं आह्वान करने के लिए अंत का मतलब है पर। आप वहां एक तर्क भी जोड़ सकते हैं जो आपके अनाम फ़ंक्शन का तर्क बन जाएगा। मैं jQuery के साथ अक्सर ऐसा करता हूं, और आप देख सकते हैं कि क्यों ...
(function($) {
// Now I can use $, but it won't affect any other library like Prototype
})(jQuery);
इवान ट्रिंबोली ने अपने जवाब में बाकी को शामिल किया है ।
उपरोक्त कोड क्या कर रहा है लाइन 1 पर एक अनाम फ़ंक्शन बना रहा है, और फिर इसे 0 तर्क के साथ लाइन 3 पर कॉल कर रहा है। यह उस पुस्तकालय के भीतर परिभाषित सभी कार्यों और चर को प्रभावी ढंग से संलग्न करता है, क्योंकि सभी फ़ंक्शन केवल उस अनाम फ़ंक्शन के अंदर ही सुलभ होंगे।
यह अच्छा अभ्यास है, और इसके पीछे तर्क यह है कि वैश्विक नाम स्थान को चर और कार्यों के साथ प्रदूषित करने से बचा जाए, जो कि पूरे साइट पर जावास्क्रिप्ट के अन्य टुकड़ों द्वारा बंद किया जा सकता है।
यह स्पष्ट करने के लिए कि फ़ंक्शन को कैसे कहा जाता है, सरल उदाहरण पर विचार करें:
यदि आपके पास जावास्क्रिप्ट की यह एकल पंक्ति शामिल है, तो यह स्पष्ट रूप से कॉल किए बिना स्वचालित रूप से आह्वान करेगा:
alert('hello');
तो, उस विचार को लें, और इसे इस उदाहरण पर लागू करें:
(function() {
alert('hello')
//anything I define in here is scoped to this function only
}) (); //here, the anonymous function is invoked
अंतिम परिणाम समान है, क्योंकि अनाम फ़ंक्शन पिछले उदाहरण की तरह ही लागू किया गया है।
//here, the anonymous function is invoked, सरल, लेकिन मैंने इसे पहले नहीं देखा :)
function(){ // some code here }
जावास्क्रिप्ट में एक अनाम फ़ंक्शन को परिभाषित करने का तरीका है। वे आपको एक फ़ंक्शन को किसी अन्य फ़ंक्शन के संदर्भ में निष्पादित करने की क्षमता दे सकते हैं (जहां आपके पास अन्यथा वह क्षमता नहीं हो सकती है)।