उत्तर मुझे जवाब खोजने में मदद के लिए यूसुफ को अद्यतन 2/उत्तर में नीचे एंबेडेडडेथमैच: स्वयं निष्पादित बेनामी समारोह -वसेस- "नया समारोह"
धन्यवाद (हालांकि मैं यह पसंद नहीं है =) । http://yuiblog.com/blog/2007/06/12/module-pattern/:
मूल प्रश्न
सर्वोत्तम प्रथाओं पर कुछ शोध करते समय जब जावास्क्रिप्ट में Namepsaces का उपयोग कर, मैं "मॉडल पैटर्न" की इस परिभाषा बारे में जाना।
मैं आमतौर पर इस पैटर्न का उपयोग कर रहा हूं क्योंकि मैंने इसे YUI2 साल पहले देखा था, और यह आलेख अवधारणा का एक अच्छा अवलोकन देता है। लेकिन यह क्या नहीं छूता है, "नया कार्य" के स्थान पर "स्वयं निष्पादित अज्ञात कार्य" का उपयोग क्यों किया जाता है। यह टिप्पणियों में पूछा गया था, लेकिन लेखक द्वारा अच्छी तरह से वर्णित नहीं किया गया था। चूंकि यह आलेख 4+ वर्ष पुराना है (और मुझे ऑनलाइन कहीं और जवाब नहीं मिला है) मैंने सोचा कि मैं इसे यहां लाऊंगा।
यह पहले से बंद होने के भीतर है, तो? (देखें: Why is this function wrapped in parentheses, followed by parentheses? जो मेरे प्रश्न का उत्तर भी नहीं देता है =)।
निम्नलिखित सेटअप कोड मान लिया जाये ..
var MyNamespace = window.MyNamespace || {};
इनमें से कौन सा पसंद किया जाता है और क्यों?
MyNamespace.UsingNew = new function() {
var fnPrivate = function() {
return "secrets1";
};
this.property = "value1";
this.method = function() {
return "property = " + this.property + ' ' + fnPrivate();
}
};
MyNamespace.UsingSelfEx = (function() { //# <- Added "pre-parens" suggested by chuckj
var fnPrivate = function() {
return "secrets2";
};
var fnReturn = {};
fnReturn.property = "value2";
fnReturn.method = function() {
return "property = " + this.property + ' ' + fnPrivate();
}
return fnReturn;
})();
अद्यतन:
ऐसा नहीं है कि jQuery की तरह, सभी शांत बच्चों को प्रयोग कर रहे हैं "स्व निष्पादित बेनामी कार्य" लगता है (Seaf)! लेकिन मुझे यह नहीं मिला है, क्योंकि मुझे लगता है कि उपयोग करने के लिए यह बहुत साफ है। उपयोग करने के लिए नए दृष्टिकोण के रूप में आप परिभाषा पर सार्वजनिक कार्यों का पर्दाफाश करते हैं (बदले में नीचे की जरूरत है जिसे अलग से बनाए रखा जाना चाहिए या इनलाइन ऑब्जेक्ट का उपयोग करने के लिए मजबूर होना चाहिए अंकन)।
की जरूरत नहीं "है कि = इस" कारणों की एक संख्या के लिए मेरे लिए पानी नहीं रखता है के लिए तर्क:
- आदेश "var कि इस =" से बचने के लिए आप अंत में या तो एक बनाने " var obj "प्लस एक रिटर्न कथन (बनाए रखने के लिए। जनता की एक अलग परिभाषा है) या अपने सार्वजनिक गुण/विधियों के लिए इनलाइन ऑब्जेक्ट नोटेशन (वापसी {1,2,3}) का उपयोग करने के लिए मजबूर होना पड़ रहा है।
- आप हमेशा कक्षा/नामस्थान के शीर्ष पर "var that = this" का एक निजी चर बना सकते हैं और पूरे "उस" का उपयोग कर सकते हैं।
अब ... मुझे लगता है कि मेरी विकास शैली अच्छी तरह से कर सकती है। उपयोग करने के लिए नए पैटर्न को प्रबंधित करना बहुत आसान है। मेरे "निजी" कार्य प्रकृति में लगभग हमेशा "स्थैतिक" होते हैं, इसलिए मुझे संदर्भ में वैसे भी पास करना होगा ("इस" की आवश्यकता को आपूर्ति करना)। मैंने "संक्षेप" नामस्थान का उपयोग करने की आदत भी ली है, इसलिए जब मुझे "इस" तक पहुंच की आवश्यकता होती है तो मैं बस पूर्ण उद्देश्य के बजाय "संक्षिप्त नाम" नामस्थान के माध्यम से पूर्ण वस्तु का संदर्भ देता हूं। उदा .:
var PrivateFunct = function() {
var rThis = Cn._.val; //# The abbreviated form of Cn.Renderer.Form.Validation
//...
};
या अगर यह एक निजी स्टेटिक समारोह ...
var PrivateStaticFunct = function(oContext) {
//...
};
अन्य तो ऊपर दिए गए कारण है, मैं व्यक्तिगत रूप से .UsingNew दृष्टिकोण और अधिक स्रोत में पठनीय हैं।मेरे पास एक बहुत व्यापक कोडबेस है जो .UsingNew पैटर्न का उपयोग करता है: http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/Validation functionality के साथ शायद आपके सिर को लगभग 1 में पढ़ने के लिए सबसे आसान है। मैं कुछ एसईएएफ कार्यों का भी उपयोग करता हूं (ErrorMessages.js.aspx देखें) लेकिन केवल तभी जब वे समझ में आते हैं।
मैं कल्पना नहीं कर सका कि सार्वजनिक इंटरफेस का पर्दाफाश करने के लिए अलग-अलग रिटर्न बनाए रखना है! नीरस
अब, मुझे गलत मत समझो, वहां कई जगहें हैं जहां बंद करने को लागू करने के लिए एक एसएएएफ बहुत उपयोगी है, लेकिन मुझे व्यक्तिगत रूप से लगता है कि यह वस्तुओं के भीतर अत्यधिक उपयोग किया जाता है।
अद्यतन 2:
प्रति डगलस Crockford:
आगे प्रतिबिंब (और उसके जवाब के तहत यूसुफ के साथ एक विस्तारित चर्चा करने के लिए धन्यवाद) पर वहाँ कुछ नियम है कि इस डेथमैच लागू किया जा सकता हो रहा है (देखें: JS we hardly new Ya) बेनामी कार्यों 'नई' कीवर्ड का उपयोग कभी नहीं करना चाहिए क्योंकि:
- यह एक वस्तु एल उपयोग करने के लिए तेजी से होता है iteral।
- फ़ंक्शन को आमंत्रित करने के लिए नए का उपयोग करके, ऑब्जेक्ट एक बेकार प्रोटोटाइप ऑब्जेक्ट पर रखता है। यह बिना किसी परेशानी के लाभ के स्मृति को बर्बाद कर देता है। यदि हम नए का उपयोग नहीं करते हैं, तो हम श्रृंखला में बर्बाद प्रोटोटाइप ऑब्जेक्ट नहीं रखते हैं। (नोट: प्रोटोटाइप कॉल कन्स्ट्रक्टर परिभाषा के बाद आती है, और एसईएएफ या "नया" अज्ञात फ़ंक्शंस को निकाल दिया जाता है, इसलिए एक व्यक्ति उनके साथ प्रोटोटाइप का उपयोग नहीं कर सकता)
- किसी ऑब्जेक्ट का उपयोग करने के लिए इसे कम कोड की आवश्यकता होती है। (जबकि सच है, मुझे असहमत होना है क्योंकि मैं ऑब्जेक्ट शाब्दिक नोटेशन से नफरत करता हूं, मैं इसका उपयोग करना पसंद करूंगा; इसके बजाए, जैसा कि यह अधिक पठनीय है)।
- फ़ंक्शन के सामने सीधे नया डालना अच्छा विचार नहीं है। उदाहरण के लिए, नए कार्य को नई वस्तुओं के निर्माण में कोई फायदा नहीं होता है।
तो यह मांस और इस मामले के आलू लगता है यह है: Seaf की गति और कम भूमि के ऊपर (कोई अनावश्यक प्रोटोटाइप वस्तु) की वजह से var obj = new function() {...};
के लिए बेहतर कर रहे हैं। आपको जो पीड़ित होना है वह तथ्य यह है कि आपको ऑब्जेक्ट शाब्दिक नोटेशन (इसलिए, आपके सार्वजनिक सदस्यों के बीच के बजाय) का उपयोग करने के लिए मजबूर किया जाता है या वापसी वस्तु में सार्वजनिक वस्तुओं की एक अलग सूची बनाए रखने के लिए मजबूर किया जाता है।
एसईएएफ की सलाह नहीं दी जाती है जब आप किसी ऑब्जेक्ट कन्स्ट्रक्टर के रूप में काम करने के लिए फ़ंक्शन का इरादा रखते हैं instanceof
अपेक्षित कार्य नहीं करेगा (देखें: creating objects from JS closure: should i use the “new” keyword?)।
उत्तर:
- यदि यह एक गुमनाम समारोह एक सिंगलटन/वैश्विक स्टेटिक उदाहरण के रूप में कार्य करने के लिए, Seaf का उपयोग इरादा है।
यदि आप इसे
Constructor
(संभावित रूप से एकाधिक ऑब्जेक्ट्स का प्रतिनिधित्व करने के लिए) के रूप में कार्य करने का इरादा रखते हैं या आप .prototype का उपयोग कर रहे हैं, तो "मानक" फ़ंक्शन परिभाषा का उपयोग करें और "नया", उदाहरण के साथ ":function PseudoClass1() {}
var PseudoClass2 = function() {};
var myClass1 = new PseudoClass1();
var myClass2 = new PseudoClass2();
मुझे कहना है, मैं इस जवाब के साथ खुश नहीं हूँ;) मैं .UsingNew पैटर्न ढूंढ कोडबेस में पठनीय, लेकिन यह धीमा है और इस तथ्य के कारण एसएएएफ के बाद अधिक मेमोरी का उपयोग करता है ई अप्रयुक्त प्रोटोटाइप संदर्भ तत्काल और ऑब्जेक्ट श्रृंखला में छोड़ा गया है।
यहां रोचक सामग्री का एक बहुत ... जब से तुम दृढ़ता से UsingNew मैं डॉन पसंद करते हैं (देर से पार्टी मुझे पता है .. करने के लिए) यह नहीं लगता कि अकेले अप्रयुक्त प्रोटोटाइप आपके दृष्टिकोण को बदलने के लिए पर्याप्त कारण है ... यह स्मृति की एक बहुत ही कम मात्रा है (तुलना के लिए, यह मॉड्यूल पैटर्न का उपयोग करने वाले कोडर की मात्रा से अधिक न्यूनतम है जो उपयोग नहीं करकर बलिदान के लिए तैयार हैं प्रोटोटाइप।) –
अज्ञात फ़ंक्शन दृष्टिकोण के संदर्भ में, यदि आप "fnReturn" जैसी चीज़ों के बदले वापसी चर "स्वयं" कहा जाता है तो शायद यह अधिक पठनीय प्रतीत होता है। आप फ़ंक्शन में किसी खाली वस्तु को भी पास कर सकते हैं और "स्वयं" पैरामीटर हो सकते हैं; फिर रिटर्न स्टेटमेंट और "इस" के बजाय "स्वयं" के उपयोग से सहायता करें, फ़ंक्शन का बॉडी आपके पहले उदाहरण के समान होगा। –
आपको [निश्चित रूप से 'नए फ़ंक्शन' का उपयोग नहीं करना चाहिए] (http://stackoverflow.com/a/10406585/1048572) – Bergi