उदाहरण के साथ जावास्क्रिप्ट मॉड्यूल पैटर्न [बंद]


136

मुझे कोई सुलभ उदाहरण नहीं मिल रहा है कि दो (या अधिक) विभिन्न मॉड्यूल एक साथ काम करने के लिए कैसे जुड़े हैं।

इसलिए, मैं पूछना चाहता हूं कि क्या किसी के पास एक उदाहरण लिखने के लिए समय है कि कैसे मॉड्यूल एक साथ काम करते हैं।


पिछले चार वर्षों में यह सब बदल गया है, लेकिन उत्साही अति-मॉडरेशन के लिए धन्यवाद, यह आउट-ऑफ-डेट जानकारी हमेशा के लिए लटकाएगी । यहाँ ESN मॉड्यूल पर MDN का पेज है
bbsimonbb

जवाबों:


256

मॉड्यूलर डिजाइन पैटर्न के लिए दृष्टिकोण करने के लिए, आपको पहले इन अवधारणा को समझने की आवश्यकता है:

तुरंत-आमंत्रित समारोह अभिव्यक्ति (IIFE):

(function() {
      // Your code goes here 
}());

ऐसे दो तरीके हैं जिनसे आप कार्यों का उपयोग कर सकते हैं। 1. समारोह की घोषणा 2. समारोह की अभिव्यक्ति।

यहाँ फ़ंक्शन एक्सप्रेशन का उपयोग कर रहे हैं।

नाम स्थान क्या है? अब अगर हम ऊपर के कोड में नाम स्थान जोड़ते हैं तो

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

जेएस में बंद क्या है?

इसका मतलब है कि अगर हम किसी फ़ंक्शन को किसी भी चर दायरे के साथ / किसी अन्य फ़ंक्शन के अंदर घोषित करते हैं (जेएस में हम किसी फ़ंक्शन को किसी अन्य फ़ंक्शन के अंदर घोषित कर सकते हैं!) तो यह उस फ़ंक्शन गुंजाइश को हमेशा गिना जाएगा। इसका मतलब है कि बाहरी फ़ंक्शन में कोई भी चर हमेशा पढ़ा जाएगा। यह एक ही नाम के साथ वैश्विक चर (यदि कोई हो) नहीं पढ़ेगा। यह नामकरण संघर्ष से बचने के लिए मॉड्यूलर डिजाइन पैटर्न का उपयोग करने के उद्देश्य में से एक भी है।

var scope = "I am global";
function whatismyscope() {
    var scope = "I am just a local";
    function func() {return scope;}
    return func;
}
whatismyscope()()

अब हम इन तीन अवधारणाओं को लागू करेंगे जिनका उल्लेख मैंने अपने पहले मॉड्यूलर डिजाइन पैटर्न को परिभाषित करने के लिए किया था:

var modularpattern = (function() {
    // your module code goes here
    var sum = 0 ;

    return {
        add:function() {
            sum = sum + 1;
            return sum;
        },
        reset:function() {
            return sum = 0;    
        }  
    }   
}());
alert(modularpattern.add());    // alerts: 1
alert(modularpattern.add());    // alerts: 2
alert(modularpattern.reset());  // alerts: 0

ऊपर दिए गए कोड के लिए jsfiddle।

उद्देश्य बाहरी दुनिया से परिवर्तनशील पहुंच को छिपाना है।

उम्मीद है की यह मदद करेगा। शुभ लाभ।


क्या बेहतर होगा कि आईआईएफएफ का नाम दिया जाए? सिमेंटिक उद्देश्यों और बेहतर स्टैक ट्रेसिंग के लिए? क्या यह कोड में कुछ भी बदल सकता है?
जीरोेन

2
आपका पहला उदाहरण (function() { /* Your code goes here */}());वास्तव में एक Iife (इसके तत्काल बाद समारोह अभिव्यक्ति लागू) है, ठीक है यह गुमनाम है coz यह कोई नाम नहीं है तो आप भी यह एक IIAFE (तुरंत लागू बेनामी समारोह अभिव्यक्ति) फोन पर Iife पर अधिक देखने के लिए चाहते हो सकता है stackoverflow.com/questions/ २४२१ ९ ११ /…
बी

वापसी विवरण का उपयोग क्यों किया गया है? यदि हम {} को वापस भेजते हैं तो फ़ंक्शन और रीसेट फ़ंक्शन सार्वजनिक हो जाएगा और मुझे लगता है कि वे स्थानीय चर राशि तक पहुंच सकते हैं? क्या मैं सही हू?
मऊ

आपका दूसरा उदाहरण एक वस्तु जैसा दिखता है या मैं सही नहीं हूं?
कारण

4
यह ओपी के प्रश्न को संबोधित नहीं करता है। यह मॉड्यूल पैटर्न का वर्णन है कि ओपी के रूप में कई मॉड्यूल एक साथ कैसे काम कर सकते हैं इसका उदाहरण नहीं है।
एरिक ट्राटमैन

39

मैं वास्तव में किसी को भी इस विषय में प्रवेश करने की सलाह दूंगा Addy Osmani की मुफ्त पुस्तक:

"लर्निंग जावास्क्रिप्ट डिज़ाइन पैटर्न"।

http://addyosmani.com/resources/essentialjsdesignpatterns/book/

जब मैंने अधिक रख-रखाव जावास्क्रिप्ट लिखना शुरू किया था और तब भी मैं इसे एक संदर्भ के रूप में इस्तेमाल कर रहा था, तब इस पुस्तक ने मेरी बहुत मदद की। उनके विभिन्न मॉड्यूल पैटर्न कार्यान्वयन पर एक नज़र है, वह उन्हें वास्तव में अच्छी तरह से समझाता है।


मैं अपने लेख को "निश्चित मॉड्यूल पैटर्न" पर भी पढ़ने की सलाह दूंगा, जो कि Addy
Osmani


4
स्टोयन की पुस्तक अधिक व्यापक है। यह सिर्फ उच्च स्तर के पैटर्न से अधिक कवर करता है, लेकिन अन्य जेएस सर्वोत्तम प्रथाओं के बारे में अधिक गहराई से बात करता है।
कोड Novitiate

1
"लर्निंग जावास्क्रिप्ट डिज़ाइन पैटर्न" की समीक्षा amazon.com/product-reviews/1449331815
एड्रियन बी

3
Stoyan Stefanov amazon.com/product-reviews/0596806752 द्वारा "जावास्क्रिप्ट पैटर्न" की समीक्षा । नोट: जो "लर्निंग जावास्क्रिप्ट डिज़ाइन पैटर्न" से बहुत बेहतर लगता है
एड्रियन बन

19

मुझे लगा कि मैं उपरोक्त उत्तर पर इस बात का विस्तार करूंगा कि आप किसी एप्लिकेशन में एक साथ मॉड्यूल कैसे फिट करेंगे। मैं इस बारे में doug crockford पुस्तक में पढ़ा था, लेकिन जावास्क्रिप्ट के लिए नया होने के नाते यह सब अभी भी थोड़ा रहस्यमय था।

मैं एसी # पृष्ठभूमि से आता हूं इसलिए मैंने कुछ शब्दावली जोड़ी है जो मुझे वहां से उपयोगी लगती है।

एचटीएमएल

आपके पास कुछ kindof शीर्ष स्तर की html फ़ाइल होगी। यह आपकी परियोजना फ़ाइल के रूप में सोचने में मदद करता है। आपके द्वारा प्रोजेक्ट में जोड़ी गई प्रत्येक जावास्क्रिप्ट फ़ाइल इस में जाना चाहती है, दुर्भाग्य से आपको इसके लिए टूल सपोर्ट नहीं मिल रहा है (मैं आईडिया का उपयोग कर रहा हूँ)।

आपको इस तरह से स्क्रिप्ट टैग के साथ प्रोजेक्ट में फ़ाइलें जोड़ने की आवश्यकता है:

        <script type="text/javascript" src="app/native/MasterFile.js" /></script>
        <script type="text/javascript" src="app/native/SomeComponent.js" /></script>

ऐसा प्रतीत होता है कि टैग गिरने से चीजें विफल हो जाती हैं - जबकि यह जैसा दिखता है xml यह वास्तव में क्रेज़ियर नियमों के साथ कुछ है!

नेमस्पेस फाइल

MasterFile.js

myAppNamespace = {};

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

मॉड्यूल (रों)

SomeComponent.js

myAppNamespace.messageCounter= (function(){

    var privateState = 0;

    var incrementCount = function () {
        privateState += 1;
    };

    return function (message) {
        incrementCount();
        //TODO something with the message! 
    }
})();

हम यहां क्या कर रहे हैं, हमारे आवेदन में एक चर के लिए एक संदेश काउंटर फ़ंक्शन प्रदान कर रहा है। यह एक फ़ंक्शन है जो एक फ़ंक्शन देता है जिसे हम तुरंत निष्पादित करते हैं

अवधारणाओं

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

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

आप इस शैली का उपयोग कंस्ट्रक्टर्स को परिभाषित करने के लिए एक फ़ंक्शन वापस करके भी कर सकते हैं जो किसी ऑब्जेक्ट को फ़ंक्शन के संग्रह के साथ लौटाता है और इसे तुरंत कॉल नहीं करता है।


6

यहां https://toddmotto.com/mastering-the-module-pattern आप पैटर्न को अच्छी तरह से समझा सकते हैं। मुझे लगता है कि मॉड्यूलर जावास्क्रिप्ट के बारे में दूसरी बात यह है कि कैसे कई फ़ाइलों में अपने कोड संरचना है। बहुत से लोग आपको एएमडी के साथ जाने के लिए यहां सलाह दे सकते हैं, फिर भी मैं अनुभव से कह सकता हूं कि आप कई HTTP अनुरोधों के कारण धीमी पृष्ठ प्रतिक्रिया के साथ किसी बिंदु पर समाप्त हो जाएंगे। जिस तरह से आपके जावास्क्रिप्ट मॉड्यूल (एक फ़ाइल के प्रति एक) कॉमनजेएस मानक के बाद एक फ़ाइल में पूर्व-संकलन है। यहाँ नमूने देखें http://dsheiko.github.io/cjsc/


सभी एएमडी कार्यान्वयन भी एक ही फाइल में प्रीकंप्लिमेंटेशन प्रदान करते हैं।
आई-लिन कुओ

1
यह सही है, लेकिन परिणामी अनुकूलित फ़ाइल के लिए लोडर लाइब्रेरी की आवश्यकता होती है (बस इसे r.js v2.1.14 के साथ फिर से जांचा जाता है), जो आमतौर पर काफी वजनदार होता है। जैसे ही हमने कोड संकलित किया है हमें अतुल्यकालिक रूप से भरी हुई निर्भरता को हल करने की आवश्यकता नहीं है, हमें इस पुस्तकालय की आवश्यकता नहीं है। जरा विचार करें: हम मॉड्यूल को एएमडी में लपेटते हैं, इसका मतलब है कि एएसक्यूएन। लोड हो रहा है, तो उन्हें एक एकल फ़ाइल (अब अलग लोडिंग नहीं) में संकलित करें, लेकिन उन्हें संबोधित करने के लिए पूरी लाइब्रेरी लोड करें (अब क्या अनावश्यक है)। यह मेरे लिए एक इष्टतम तरीका के रूप में नहीं लगता है। जब हम अतुल्यकालिक रूप से लोड नहीं करते हैं तो AMD बिल्कुल क्यों?
दिमित्री शिकोओ

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

दोनों प्रारूप CommonJS मॉड्यूल / 2.0 के लिए मान्य पथ हैं और समान मापनीयता प्रदान करते हैं। जैसा कि मेरे लिए - सीजेएस मॉड्यूल / 1.1 (कॉमनजस द्वारा मेरा मतलब है) के साथ काम करना बहुत आसान है, कोड क्लीनर दिखता है।
दिमित्री शिकोओ

मुझे AMD के ऐसे लाभ मिले हैं जैसे: * केवल जावास्क्रिप्ट फ़ाइलों से अधिक लोड कर सकते हैं; * पथ उपनाम; ठीक है, कॉमनजेएस कंपाइलर इन्हें हल करता है - यह गैर-जावासिप्ट / जेएसएन निर्भरता को डेटा के रूप में लोड करता है और बिल्ड कॉन्फ़िगरेशन (उपनामों सहित) के साथ प्रदान किया जा सकता है। एकमात्र नुकसान यह है कि इसके निर्माण की आवश्यकता है। लेकिन आजकल हर कोई सीएसएस पूर्व प्रोसेसर के लिए परियोजना का निर्माण करता है। तो यह ग्रंट / गुलप के लिए एक अतिरिक्त कार्य जोड़ने के बारे में है ...
दिमित्री शिकोओ

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