2013-02-08 67 views
5

RequJS और Node.js (सामान्य रूप से प्लस जावास्क्रिप्ट) की मेरी सीमित समझ के साथ, मैं आमतौर पर कुछ प्रसिद्ध जावास्क्रिप्ट पुस्तकालयों के स्रोत पर एक नज़र डालता हूं। जब भी मैं कुछ इस तरह देखें:यह जावास्क्रिप्ट कोड (RequJS और Node.js के लिए मॉड्यूल पैटर्न) क्यों काम करता है?

(// Wrapping 
    function (root, factory) { 
     if (typeof exports === 'object') { // Node.js 

      var underscore = require('underscore'); 
      var backbone = require('backbone'); 

      module.exports = factory(underscore, backbone); 

     } else if (typeof define === 'function' && define.amd) { // Require.JS 

      define(['underscore', 'backbone'], factory); 

     } 
    }(this, function (_, Backbone) { // Factory function, the implementation 
     "option strict"; 

     function Foo() {} 

     return Foo; // Export the constructor 
    }) 
); // Wrapping 

क्या मैं (उम्मीद) समझ सकते हैं:

  • जब स्क्रिप्ट एक <script> टैग में uncluded है उस अज्ञात फ़ंक्शन कोड लपेटता स्वचालित रूप से क्रियान्वित किया जाता है
  • यह कोड RequJS और Node.js (if बहुत शुरुआत में चेक) दोनों के साथ काम करता है; factory फ़ंक्शन का परिणाम या तो module.exports (Node.js) को सौंपा गया है या define फ़ंक्शन (RequJS) के तर्क के रूप में उपयोग किया जाता है।

Q1: कैसे इस कोड RequireJS और Node.js बिना काम करता है? if और else if चेक विफल हो जाएंगे, factory फ़ंक्शन कभी निष्पादित नहीं होता है और स्क्रिप्ट वापस नहीं आती हैं।

क्यू 2: thisroot तर्क के रूप में पास करने का क्या उद्देश्य है? यह इस्तेमाल कभी नहीं किया है

+1

क्या आप सुनिश्चित हैं कि यह RequJS या Node.js के बिना काम करता है? जावास्क्रिप्ट की मेरी सीमित समझ (और यह संभवतः गलत है) [JSFiddle] (http://jsfiddle.net/aM3ZT/) मुझे लगता है कि आप Foo() –

+0

@nekman Ahh तक नहीं पहुंच सकते हैं, मुझे लगता है कि कम से कम बैकबोन उपलब्ध है । यह स्मार्ट –

+0

@JasonSperske 100% पर निश्चित नहीं है, लेकिन नेक्कन उत्तर देखें ... – gremo

उत्तर

5

असल में मुझे लगता है कि आपके प्रश्न में फिसल गया कोड ब्राउज़र ग्लोबल्स के साथ काम नहीं करेगा। इस स्निप किए गए पैटर्न को यूएमडी - यूनिवर्सल मॉड्यूल डेफिनिशन कहा जाता है। वास्तव में इस पैटर्न के कई रूपों देखते हैं, तो आप https://github.com/umdjs/umd

प्रश्नों के लिए के रूप में के बारे में अधिक उदाहरण ब्राउज़ कर सकते हैं:

Q1 यह स्निपेट RequireJS या किसी अन्य एएमडी लोडर बिना ब्राउज़रों में काम नहीं करेगा, के लिए स्पष्ट कारण - नोडजेएस के लिए केवल दो चेक - फ़ंक्शन को परिभाषित करते हैं, इसलिए एएमडी लाइब्रेरी का उपयोग किए बिना फैक्ट्री फ़ंक्शन नहीं कहा जाएगा।

बस ब्राउज़र वैश्विक

if (typeof exports === 'object') { // Node.js 
    var underscore = require('underscore'); 
    var backbone = require('backbone'); 
    module.exports = factory(underscore, backbone); 

} else if (typeof define === 'function' && define.amd) { // Require.JS 
    define(['underscore', 'backbone'], factory); 
} else { 
    // Browser globals 
    factory(root._, root.Backbone); 
} 

ध्यान दें कि हम आवरण समारोह के लिए पारित जड़ वस्तु का इस्तेमाल किया और के रूप में nekman ने बताया यह ब्राउज़र वातावरण में window पर सेट हो जाएगा के लिए एक और शर्त जोड़ बुलाया कारखाने समारोह बनाने के लिए, इसलिए हम उस खिड़की पर कारखाने में परिभाषित वैश्विक वस्तुओं को पास करते हैं, इन वस्तुओं को आमतौर पर पृष्ठ पर अन्य script टैग द्वारा परिभाषित किया जाता है। उम्मीद है कि यह आपके दूसरे प्रश्न का उत्तर देगा।

+0

+1, UMD लिंक के लिए धन्यवाद! जैसा कि मैंने कहा था कि मैं जावास्क्रिप्ट के बारे में सीख रहा हूं और मुझे समझ में नहीं आ रहा है कि कोई भी Node.js या Requ.JS का उपयोग न करने पर 'Foo' कन्स्ट्रक्टर तक कैसे पहुंच सकता है। एकमात्र तरीका 'root.Foo = factory (root._, root.Backbone) लिखना है, है ना? – gremo

+0

असल में मैं यहाँ मेरी टिप्पणी का जवाब मिल गया है: https://github.com/umdjs/umd/blob/master/returnExports.js – gremo

+0

हाँ, इस तरह से यह करने के लिए, आप बस अपने ऑब्जेक्ट प्रदान ('है Foo') और यदि हम ब्राउज़र में हैं तो हमें इसे 'रूट' (जो विंडो है) में जोड़ना चाहिए ताकि अन्य मॉड्यूल इसे देख सकें। –

2

Q1: दोनों if और else if विफल रहता है, ग्रहण करने के लिए केवल एक चीज है कि underscore और Backbone एक <script> टैग से भरी हुई है है। थोड़ी देर पहले, added a commitBackbone.localStorage plugin पर एक ही धारणा थी।

Q2:this "वैश्विक वस्तु" (एक ब्राउज़र वातावरण में window और global एक Node.js वातावरण में) को इंगित करेंगे। आपके मामले में, इसका उपयोग नहीं किया जाता है और इसमें पारित होने की आवश्यकता नहीं होती है। factory अकेले पर्याप्त होगा।

+1

** क्यू 1 ** के लिए: मैं उन पंक्तियों को समझ नहीं पा रहा हूं जिन्हें 'if' और 'else if' विफल होने पर निष्पादित किया जा रहा है (यानी ब्राउज़र)। क्या आप इसे समझा सकते हैं? मैं 'Foo() 'तक कैसे पहुंच सकता हूं? – gremo

+1

हां, यह सही ढंग से स्पूट किया गया है! यदि दोनों विफल हो जाते हैं, तो वहां एक होना चाहिए: 'else {factory (_, रीढ़ की हड्डी); } 'कारखाने तक पहुंचने के लिए और 'फू'। – nekman

+0

यहां तक ​​कि 'के साथ वापसी कारखाना (_, बैकबोन)' मैं समझ नहीं कैसे, कब साथ ''