2012-03-20 9 views
17

उत्तर मुझे जवाब खोजने में मदद के लिए यूसुफ को अद्यतन 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 पैटर्न ढूंढ कोडबेस में पठनीय, लेकिन यह धीमा है और इस तथ्य के कारण एसएएएफ के बाद अधिक मेमोरी का उपयोग करता है ई अप्रयुक्त प्रोटोटाइप संदर्भ तत्काल और ऑब्जेक्ट श्रृंखला में छोड़ा गया है।

+1

यहां रोचक सामग्री का एक बहुत ... जब से तुम दृढ़ता से UsingNew मैं डॉन पसंद करते हैं (देर से पार्टी मुझे पता है .. करने के लिए) यह नहीं लगता कि अकेले अप्रयुक्त प्रोटोटाइप आपके दृष्टिकोण को बदलने के लिए पर्याप्त कारण है ... यह स्मृति की एक बहुत ही कम मात्रा है (तुलना के लिए, यह मॉड्यूल पैटर्न का उपयोग करने वाले कोडर की मात्रा से अधिक न्यूनतम है जो उपयोग नहीं करकर बलिदान के लिए तैयार हैं प्रोटोटाइप।) –

+1

अज्ञात फ़ंक्शन दृष्टिकोण के संदर्भ में, यदि आप "fnReturn" जैसी चीज़ों के बदले वापसी चर "स्वयं" कहा जाता है तो शायद यह अधिक पठनीय प्रतीत होता है। आप फ़ंक्शन में किसी खाली वस्तु को भी पास कर सकते हैं और "स्वयं" पैरामीटर हो सकते हैं; फिर रिटर्न स्टेटमेंट और "इस" के बजाय "स्वयं" के उपयोग से सहायता करें, फ़ंक्शन का बॉडी आपके पहले उदाहरण के समान होगा। –

+0

आपको [निश्चित रूप से 'नए फ़ंक्शन' का उपयोग नहीं करना चाहिए] (http://stackoverflow.com/a/10406585/1048572) – Bergi

उत्तर

7
एक बात के लिए

, इस पैटर्न:

MyNamespace.UsingNew = new function() { 
    var fnPrivate = function() { 

     //what's this in here? 

     return "secrets1"; 
    }; 

    this.property = "value1"; 
    this.method = function() { 

     //what's this in here? 

     return "property = " + this.property + ' ' + fnPrivate(); 
    } 
}; 
  • एक वस्तु है, जो एक निर्माता समारोह का उपयोग कर मॉडलिंग की है का एक उदाहरण बनाने के लिए 'नई' कीवर्ड का उपयोग करता है। "नया" उपयोग करना भूल जाते हैं, आप किसी ऑब्जेक्ट के बजाय MyNamespace.UsingNew() फ़ंक्शन बनाने का नाम समाप्त कर देंगे।

  • यह एक कन्स्ट्रक्टर फ़ंक्शन है, और अभी तक एक ऑब्जेक्ट का उदाहरण नहीं है (जब तक कि आप इसे नया उपयोग नहीं करते)। ऑब्जेक्ट से संबंधित होने के लिए आपको "यह" उपयोग करने की आवश्यकता है। यह केवल गुंजाइश की समस्याएं जोड़ता है, खासकर जब आप इसमें अधिक फ़ंक्शंस करते हैं, और "यह" का मूल्य समय-समय पर बदल जाएगा (और कंसोल आपको बताए जाने तक आप इसे तब तक नहीं देख पाएंगे)। "इस" के मूल्य को बचाने के लिए self=this या that=this से परिचित?

    • आप इसे के बाद से 'नई' का उपयोग करने की जरूरत नहीं है: यह काफी देखा है जब otherhand पर इस पद्धति

    उपयोग करते हुए, अगले पैटर्न कुछ बेहतर (मेरे लिए) है, क्योंकि एक वस्तु देता है।

  • का उपयोग नहीं "इस" के बाद से यह पहले से ही एक वस्तु देता है। आपको "यह" भी आवश्यकता नहीं है।

भी, मैं अन्य पैटर्न इस तरह के निर्माण पसंद करते हैं:

ns.myobj = (function(){ 

    //private 
    var _privateProp = ''; 
    var _privateMeth = function(){}; 

    //public 
    var publicProp = ''; 
    var publicMeth = function(){}; 

    //expose public 
    return { 
     prop:publicProp, 
     meth:publicMeth 
    }; 
}()); 
+0

सबसे पहले, एक महान जवाब के लिए धन्यवाद! – Campbeln

+0

मेरी अज्ञानता को क्षमा करें, लेकिन अगर आप "नया" कीवर्ड भूल जाते हैं और किसी ऑब्जेक्ट की बजाय फ़ंक्शन लौटाते हैं, तो क्या अंतर है? मैं कार्यक्षमता अनुमान लगा रहा हूं लेकिन प्रदर्शन (ly) खराब नहीं है? आपके pref के रूप में। विधि, क्या आपको इसे एक रखरखाव नहीं मिलता है। नीचे वापसी के साथ दुःस्वप्न? मैंने हमेशा "यूसुइंगन्यू" का उपयोग किया है: [लिंक] (http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/Renderer/Form/Form.js) और उस = इस मुद्दे के लिए, क्योंकि मैं नेमस्पेस में निर्माण करता हूं, मैं केवल आवश्यक कार्यों को पूरी तरह से संबोधित करता हूं। मुझे यह दर्द कम से कम दर्द से मिलता है। वह वापसी – Campbeln

+0

इस प्रश्न पर एक नज़र डालें, जहां मैंने पूछा कि "नया" http://stackoverflow.com/q/9304473/575527 – Joseph

2

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

MyNamespace.UsingSelfEx = (function() { 
    function fnPrivate() { 
     return "secrets2"; 
    } 
    return { 
     property: "value2"; 
     method: function() { 
      return "property = " + this.property + " " + fnPrivate(); 
     } 
    } 
})(); 

आप वास्तव में, समारोह, लेकिन स्वयं को क्रियान्वित कार्यों के आसपास कोष्ठक की जरूरत नहीं है सामान्य रूप से उन्हें और पाठक की सुविधा देता है पता शुरुआत में है कि यह एक स्वयं को क्रियान्वित कार्य है।

+0

एघ, आप सही हैं! स्वयं निष्पादन कार्यों में आम तौर पर उनके चारों ओर "अतिरिक्त" माता-पिता होते हैं! मुझे आश्चर्य है कि यह इस कार्यक्षमता को करने का पसंदीदा तरीका प्रतीत होता है। जैसे-जैसे मैं दूसरी विधि का उपयोग करता हूं, मुझे कभी-कभी "यह = वह" दृष्टिकोण की आवश्यकता होती है, लेकिन मुझे लगता है कि किसी भी रूप में ऑब्जेक्ट रिटर्न करने से FAR कम दर्दनाक है। साथ ही जैसे मैं नेमस्पेस में निर्माण करता हूं, मैं आम तौर पर इस के पूर्ण नामस्थान पते का संदर्भ देता हूं। समारोह का उपयोग करने की आवश्यकता है। मैं अपने "निजी" कार्यों को "स्थैतिक" के रूप में डिजाइन करने की प्रवृत्ति करता हूं ताकि कोई संदेह न हो। नया दृष्टिकोण। – Campbeln

+0

देखें: [लिंक] (http://code.google.com/p/cn-namespace/source/browse/Cn.Web/js/Cn/Renderer/Form/Form.js)। ओह, और मैं "rThis = cn ._। Short" असाइनमेंट के बजाय "rThis = cn.Some.Long" के बजाय "संक्षेप में" नामस्थान "कोड में" सीएन ._ * * "द्वारा प्रतिनिधित्व किया गया है) .Namespace.Path ")। – Campbeln

+0

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

0

मैं इस देखा है और मुझे यह पसंद आया

var MyThing = (function(){ 

    function MyThing(args){ 
    } 

    MyThing.prototype = { 
     prototypeMethod: function() {} 
    }; 

    return MyThing; 
})(); 

इस

MyThing.create = function(args){ 
    return new MyThing(args); 
} 
कर सकते हैं

आमतौर पर यह एक और आत्म में संलग्न है समारोह का आह्वान टकराव नामकरण से बचने के लिए ।

(function({ 

})(window); 

और window वस्तु एक तर्क के रूप पारित हो जाता है, एक ऊपरी दायरे निर्दिष्ट करने के लिए।

window.MyThing = MyThing; 

इस उदाहरण का उपयोग कर सकते में, स्थैतिक चर, निजी आदि

संबंधित मुद्दे