नोड.जेएस वैश्विक चर?


208

मैंने यहां पूछा: नोड.जेएस को विरासत की आवश्यकता है?

और मुझे बताया गया कि मैं वेरिएबल को वैरिएबल स्कोप पर सेट कर सकता हूं।

यह मेरे लिए काम नहीं करता है।

अर्थात:

_ = require('underscore');

आवश्यक फ़ाइलों पर _ उपलब्ध नहीं करता है। मैं एक्सप्रेस के साथ सेट कर सकता हूं app.setऔर हालांकि यह कहीं और उपलब्ध है।

क्या कोई पुष्टि कर सकता है कि यह काम करने वाला है? धन्यवाद।


आपके पास उपरोक्त रेखा कहां है?
Jan Hančič

3
मुझे लगता है कि आपको एक नया प्रश्न शुरू नहीं करना चाहिए यदि आपके पिछले प्रश्न का उत्तर काम नहीं करता है। बल्कि वहां एक टिप्पणी जोड़ें और स्वीकृत टैग को हटा दें।
एलियनहार्ड

5
बस इसे संपादित करने से यह वर्तमान में सक्रिय प्रश्नों की सूची में दिखाई देता है।
MAK

3
का उपयोग करें exports। यह बहुत बेहतर है।
एम्मरमैन

1
शायद यह काम नहीं करता है क्योंकि आपके पास "सख्त उपयोग" है; आपकी फ़ाइल के शीर्ष पर। यह मेरे लिए उसी तरह काम करता है।
गीजा तुरी

जवाबों:


237

आप इस globalतरह का उपयोग कर सकते हैं :

global._ = require('underscore')

28
क्या आप कृपया थोड़ी और जानकारी प्रदान कर सकते हैं? क्या यह जावास्क्रिप्ट का हिस्सा है या नोड का हिस्सा है? क्या यह एक अच्छा पैटर्न है? जैसा कि मुझे ऐसा करना चाहिए या मुझे एक्सप्रेस सेट का उपयोग करना चाहिए? धन्यवाद
हैरी

4
पिछली टिप्पणी गलत है। ब्राउज़र में, windowवैश्विक वस्तु है। documentकी संपत्ति है window
G-Wiz

77
यह एक अच्छा पैटर्न नहीं है। यह मत करो। Decouple मॉड्यूल के लिए 'आवश्यकता' का उपयोग करने का सम्मेलन अच्छी तरह से सोचा गया है। आपको बिना किसी अच्छे कारण के इसका उल्लंघन नहीं करना चाहिए। मेरी प्रतिक्रिया नीचे देखें।
डेव डॉपसन

आमतौर पर ग्लोबल्स से बचा जाना चाहिए, लेकिन अगर आप वास्तव में उनका उपयोग करना चाहते हैं। नीचे दिए गए 3 कथन सभी समतुल्य हैं और वैश्विक दायरे में एक संस्करण प्रदान करेंगे: GLOBAL._ = की आवश्यकता ('अंडरस्कोर'); Global._ = आवश्यकता ('अंडरस्कोर'); _ = आवश्यकता ('अंडरस्कोर');
मेटाकूलिन

जब आप प्रोजेक्ट शुरू करते हैं तो यह थोड़ा बड़ा होने लगता है, इसे बनाए रखना दुःस्वप्न बन जाएगा। कृपया मेरे दृष्टिकोण पर एक नज़र डालें।
ओलिवर डिक्सन

219

नोड में, आप "वैश्विक" या "ग्लोबल" ऑब्जेक्ट के माध्यम से वैश्विक चर सेट कर सकते हैं:

GLOBAL._ = require('underscore'); // but you "shouldn't" do this! (see note below)

या अधिक उपयोगी ...

GLOBAL.window = GLOBAL;  // like in the browser

नोड स्रोत से, आप देख सकते हैं कि ये एक दूसरे के लिए अलियास हैं:

node-v0.6.6/src/node.js:
28:     global = this;
128:    global.GLOBAL = global;

उपरोक्त कोड में, "यह" वैश्विक संदर्भ है। सामान्यजेएस मॉड्यूल सिस्टम (जो नोड उपयोग करता है) के साथ, मॉड्यूल के अंदर "यह" वस्तु (यानी, "आपका कोड") वैश्विक संदर्भ नहीं है। इसके प्रमाण के लिए, नीचे देखें कि मैंने "यह" ऑब्जेक्ट कहाँ और इसके बाद "ग्लोबल" ऑब्जेक्ट को देखा।

console.log("\nTHIS:");
console.log(this);
console.log("\nGLOBAL:");
console.log(global);

/* outputs ...

THIS:
{}

GLOBAL:
{ ArrayBuffer: [Function: ArrayBuffer],
  Int8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Uint8Array: { [Function] BYTES_PER_ELEMENT: 1 },
  Int16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Uint16Array: { [Function] BYTES_PER_ELEMENT: 2 },
  Int32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Uint32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float32Array: { [Function] BYTES_PER_ELEMENT: 4 },
  Float64Array: { [Function] BYTES_PER_ELEMENT: 8 },
  DataView: [Function: DataView],
  global: [Circular],
  process: 
   { EventEmitter: [Function: EventEmitter],
     title: 'node',
     assert: [Function],
     version: 'v0.6.5',
     _tickCallback: [Function],
     moduleLoadList: 
      [ 'Binding evals',
        'Binding natives',
        'NativeModule events',
        'NativeModule buffer',
        'Binding buffer',
        'NativeModule assert',
        'NativeModule util',
        'NativeModule path',
        'NativeModule module',
        'NativeModule fs',
        'Binding fs',
        'Binding constants',
        'NativeModule stream',
        'NativeModule console',
        'Binding tty_wrap',
        'NativeModule tty',
        'NativeModule net',
        'NativeModule timers',
        'Binding timer_wrap',
        'NativeModule _linklist' ],
     versions: 
      { node: '0.6.5',
        v8: '3.6.6.11',
        ares: '1.7.5-DEV',
        uv: '0.6',
        openssl: '0.9.8n' },
     nextTick: [Function],
     stdout: [Getter],
     arch: 'x64',
     stderr: [Getter],
     platform: 'darwin',
     argv: [ 'node', '/workspace/zd/zgap/darwin-js/index.js' ],
     stdin: [Getter],
     env: 
      { TERM_PROGRAM: 'iTerm.app',
        'COM_GOOGLE_CHROME_FRAMEWORK_SERVICE_PROCESS/USERS/DDOPSON/LIBRARY/APPLICATION_SUPPORT/GOOGLE/CHROME_SOCKET': '/tmp/launch-nNl1vo/ServiceProcessSocket',
        TERM: 'xterm',
        SHELL: '/bin/bash',
        TMPDIR: '/var/folders/2h/2hQmtmXlFT4yVGtr5DBpdl9LAiQ/-Tmp-/',
        Apple_PubSub_Socket_Render: '/tmp/launch-9Ga0PT/Render',
        USER: 'ddopson',
        COMMAND_MODE: 'unix2003',
        SSH_AUTH_SOCK: '/tmp/launch-sD905b/Listeners',
        __CF_USER_TEXT_ENCODING: '0x12D732E7:0:0',
        PATH: '/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:~/bin:/usr/X11/bin',
        PWD: '/workspace/zd/zgap/darwin-js',
        LANG: 'en_US.UTF-8',
        ITERM_PROFILE: 'Default',
        SHLVL: '1',
        COLORFGBG: '7;0',
        HOME: '/Users/ddopson',
        ITERM_SESSION_ID: 'w0t0p0',
        LOGNAME: 'ddopson',
        DISPLAY: '/tmp/launch-l9RQXI/org.x:0',
        OLDPWD: '/workspace/zd/zgap/darwin-js/external',
        _: './index.js' },
     openStdin: [Function],
     exit: [Function],
     pid: 10321,
     features: 
      { debug: false,
        uv: true,
        ipv6: true,
        tls_npn: false,
        tls_sni: true,
        tls: true },
     kill: [Function],
     execPath: '/usr/local/bin/node',
     addListener: [Function],
     _needTickCallback: [Function],
     on: [Function],
     removeListener: [Function],
     reallyExit: [Function],
     chdir: [Function],
     debug: [Function],
     error: [Function],
     cwd: [Function],
     watchFile: [Function],
     umask: [Function],
     getuid: [Function],
     unwatchFile: [Function],
     mixin: [Function],
     setuid: [Function],
     setgid: [Function],
     createChildProcess: [Function],
     getgid: [Function],
     inherits: [Function],
     _kill: [Function],
     _byteLength: [Function],
     mainModule: 
      { id: '.',
        exports: {},
        parent: null,
        filename: '/workspace/zd/zgap/darwin-js/index.js',
        loaded: false,
        exited: false,
        children: [],
        paths: [Object] },
     _debugProcess: [Function],
     dlopen: [Function],
     uptime: [Function],
     memoryUsage: [Function],
     uvCounters: [Function],
     binding: [Function] },
  GLOBAL: [Circular],
  root: [Circular],
  Buffer: 
   { [Function: Buffer]
     poolSize: 8192,
     isBuffer: [Function: isBuffer],
     byteLength: [Function],
     _charsWritten: 8 },
  setTimeout: [Function],
  setInterval: [Function],
  clearTimeout: [Function],
  clearInterval: [Function],
  console: [Getter],
  window: [Circular],
  navigator: {} }
*/

** नोट: "GLOBAL._" सेट करने के बारे में, सामान्य तौर पर आपको बस करना चाहिए var _ = require('underscore');। हां, आप ऐसा हर एक फाइल में करते हैं जो अंडरस्कोर का उपयोग करता है, ठीक उसी तरह जैसे जावा में आप करते हैं import com.foo.bar;। इससे यह पता लगाना आसान हो जाता है कि आपका कोड क्या कर रहा है क्योंकि फाइलों के बीच लिंक 'स्पष्ट' हैं। हल्का कष्टप्रद, लेकिन एक अच्छी बात है। .... यही उपदेश है।

हर नियम का एक अपवाद है। मेरे पास ठीक एक उदाहरण है जहां मुझे "GLOBAL._" सेट करने की आवश्यकता थी। मैं "कॉन्फिग" फाइलों को परिभाषित करने के लिए एक सिस्टम बना रहा था जो मूल रूप से JSON थे, लेकिन थोड़ा अधिक लचीलेपन की अनुमति देने के लिए "JS में लिखे गए" थे। इस तरह की कॉन्फिग फाइलों में किसी 'स्टेटमेंट' की आवश्यकता नहीं होती थी, लेकिन मैं चाहता था कि अंडरस्कोर (ENTIRE सिस्टम को अंडरस्कोर और अंडरस्कोर टेम्प्लेट) पर एक्सेस किया जाए, इसलिए "कॉन्फिगरेशन" का मूल्यांकन करने से पहले, मैं "GLALAL__" सेट करूंगा। तो हाँ, हर नियम के लिए, कहीं न कहीं एक अपवाद है। लेकिन आपके पास बेहतर रूप से एक अच्छा कारण था और न केवल "मैं टाइप करने के लिए थक गया 'आवश्यकता' इसलिए मैं सम्मेलन के साथ तोड़ना चाहता हूं"।


7
ग्लोबल का उपयोग करने के पतन क्या हैं? मुझे एक अच्छे कारण की आवश्यकता क्यों है? लब्बोलुआब यह है कि मेरा ऐप काम करता है, है ना?
trusktr

26
अंततः, हाँ, यदि आप जहाज करते हैं, तो यह सब मायने रखता है। हालांकि, कुछ प्रथाओं को "सर्वोत्तम प्रथाओं" के रूप में जाना जाता है और उनका पालन करने से आमतौर पर आपके शिपिंग और / या आपके द्वारा बनाए गए कार्यों को बनाए रखने में सक्षम होता है। प्रोजेक्ट के आकार के साथ "अच्छा अभ्यास" का महत्व बढ़ता है और यह दीर्घायु है। मैंने छोटी-छोटी परियोजनाओं में सभी प्रकार के नॉटी हैक्स का निर्माण किया है जो कि एक बार लिखे गए थे, कभी-कभी (और "एकल-डेवलपर")। एक बड़े प्रोजेक्ट में, कॉर्नर कटिंग की तरह आप प्रोजेक्ट की गति को समाप्त कर देते हैं।
डेव डॉपसन

48
विशेष रूप से, वैश्विक के साथ, मुद्दा पठनीयता में से एक है। यदि आपका प्रोग्राम वैश्विक रूप से वैरिएबल का उपयोग करता है, तो इसका मतलब है कि कोड को समझने के लिए, मुझे पूरे ऐप की डायनेमिक रनटाइम स्थिति को समझना होगा। यही कारण है कि प्रोग्रामर ग्लोबल्स के लेरी हैं। मुझे यकीन है कि उनके प्रभावी ढंग से उपयोग करने के दर्जनों तरीके हैं, लेकिन हमने ज्यादातर उन्हें सिर्फ उत्पाद के रूप में जूनियर प्रोग्रामर द्वारा दुर्व्यवहार करते देखा है।
डेव डॉपसन

2
आप केवल कॉन्‍फ़िगर .jsकरने requireसे पहले अपने कॉन्‍फ़िगर को नियमित फ़ाइल में क्‍यों नहीं डाल सकते हैं ?
अज़ात

4
@Jackie - en.wikipedia.org/wiki/Singleton_pattern । यदि आप सिंगलटन पैटर्न के नक्शे पर क्या कर रहे हैं, तो यह समझ में आ सकता है। DB कनेक्शन एकल हो सकते हैं जब: 1) सेटअप महंगा होता है, 2) आप केवल कनेक्शन को एक बार सेट करना चाहते हैं, 3) कनेक्शन ऑब्जेक्ट लंबे समय तक जीवित रहता है और जीता नहीं है और नेटवर्क हिचकी की स्थिति में विफल स्थिति में प्रवेश करता है, 4) कनेक्शन ऑब्जेक्ट थ्रेड-सुरक्षित है / कई अलग-अलग कॉलर्स द्वारा साझा किया जा सकता है।
डेव डॉपसन

78

जब प्रोजेक्ट बड़ा हो जाता है, तो अन्य समाधान जो GLOBAL कीवर्ड का उपयोग करते हैं, वे / पठनीयता (+ नाम स्थान प्रदूषण और कीड़े) को बनाए रखने के लिए एक बुरा सपना हैं। मैंने कई बार यह गलती देखी है और इसे ठीक करने का झंझट था।

JS फ़ाइल का उपयोग करें और फिर मॉड्यूल निर्यात का उपयोग करें।

उदाहरण:

globals.js

var Globals = {
    'domain':'www.MrGlobal.com';
}

module.exports = Globals;

फिर यदि आप इन का उपयोग करना चाहते हैं, तो उपयोग की आवश्यकता है।

var globals = require('globals'); //<< globals.js path
globals.domain //<< Domain.

12
मैं निश्चित रूप से यूनिकॉर्न से प्यार नहीं करता, लेकिन आपके दृष्टिकोण की तरह। धन्यवाद।
जोनाटस वाकर 19

globals.domainहालांकि बदलने के बारे में क्या ?
फ़िज़िक्स

1
@iLoveUnicorns उत्तर देने के लिए धन्यवाद। मैं 'एक्सप्रेस-सत्र' जैसे विकल्पों पर ध्यान दूंगा क्योंकि मुझे मुख्य रूप से उपयोगकर्ता डेटा में लॉग को संग्रहीत करने के लिए इसकी आवश्यकता है।
फिज़िक्स

11
जबकि यह मेरी राय में बेहतर दृष्टिकोण है, यह ग्लोबल्स नहीं बनाता है और पूछे गए प्रश्न का उत्तर नहीं देता है। यह एक वैकल्पिक दृष्टिकोण है और मैं हमेशा उन लोगों को प्रोत्साहित करता हूं, हालांकि "इस थ्रेड पर एकमात्र सही उत्तर है" जैसे बयानों का सघन कॉकी-नेस यहां बस नहीं है। stackoverflow.com/help/be-nice
Thor84no

2
यह एक बेहतर तरीका हो सकता है, लेकिन अगर आप बाहरी रूप से लिखी गई स्क्रिप्ट को चलाने की कोशिश कर रहे हैं, जो वैश्विक नामस्थान में होने वाली किसी चीज़ पर निर्भर है, तो यह आपकी मदद नहीं करता है। IOW, इस सवाल का जवाब नहीं है।
binki

12

एक वैश्विक नाम स्थान के बारे में क्या पसंद है global.MYAPI = {}

global.MYAPI._ = require('underscore')

कैमिलो-मार्टिन की टिप्पणी के बाद संपादित करें : अन्य सभी पोस्टर खराब पैटर्न के बारे में बात करते हैं। इसलिए उस चर्चा को एक तरफ छोड़ दें, विश्व स्तर पर एक चर को परिभाषित करने का सबसे अच्छा तरीका (ओपी का सवाल) नेमस्पेस के माध्यम से है।

@tip: http://thanpol.as/javascript/development-use-namespaces


3
यही तो requireहै! नामस्थानों का उपयोग करना ठीक है, लेकिन global.foo = global.foo || {}सभी फाइलों, या कुछ पर सभी मत जाओ । नामस्थान को परिभाषित करने वाली फ़ाइल की आवश्यकता है। बच्चों के लिए करो।
कैमिलो मार्टिन

@ कैमिलो-मार्टिन हाय, 1) ग्लोबल को परिभाषित करके ।YAPI._ आपको इसे सभी फाइलों में परिभाषित करने की आवश्यकता नहीं है, यही वैश्विक होने का कारण है। 2) यह बच्चों के साथ कुछ भी नहीं है। यहां तक ​​कि अगर सभी कहते हैं कि यह खराब पैटर्न है, तो यह प्रोग्रामर और दी गई स्थिति पर निर्भर करता है कि वह भाषा की इस क्षमता का उपयोग कैसे करता है।
इगोर पारा

2
हां, लेकिन मान लें कि आप एक अलग फ़ाइल में किसी नेमस्पेस की कार्यक्षमता की घोषणा करते हैं। फिर आपको ऑब्जेक्ट का उपयोग करने के लिए एक फ़ाइल की आवश्यकता होती है, जो कि पीछे की ओर है और कॉमनजस और कॉमनसेंस के खिलाफ भी जाती है। यदि आपको सामान की आवश्यकता है, तो उपयोगकर्ता कोड में नाम स्थान की आवश्यकता है और नाम स्थान की आवश्यकता नहीं है। ध्यान दें, मैं नेमस्पेस के खिलाफ कुछ भी नहीं कह रहा हूं , बस यही है कि कौन किस कारण से कॉल करता है, इस पर विचार किया जा रहा है। और क्लाइंट-साइड में आपके पास क्या नोड नहीं है; आपके द्वारा उल्लिखित लिंक को एक निश्चित तरीके से (वैश्विक माध्यम से) कर रहा है क्योंकि यह ब्राउज़र के बारे में है और नोड के बारे में नहीं है।
कैमिलो मार्टिन

1
अफसोस की बात है कि आपके द्वारा पोस्ट किया गया URL केवल तभी काम करता है जब आप पीछे चल रहे स्लैश को छोड़ देते हैं;)
पात्र

10

आप सिर्फ वैश्विक वस्तु का उपयोग कर सकते हैं।

var X = ['a', 'b', 'c'];
global.x = X;

console.log(x);
//['a', 'b', 'c']

5

मैं इस बात से सहमत हूं कि कुछ भी वैश्विक स्थापित करने के लिए वैश्विक / वैश्विक नामस्थान का उपयोग करना बुरा व्यवहार है और इसे सिद्धांत रूप में ( सिद्धांत रूप में ऑपरेटिव शब्द होने के नाते) प्रयोग न करें । हालाँकि (हाँ, ऑपरेटिव) मैं इसका उपयोग कस्टम त्रुटि वर्गों की स्थापना के लिए करता हूँ:

// Some global/config file that gets called in initialisation

global.MyError = [Function of MyError];

हां, यहां वर्जित है, लेकिन यदि आपकी साइट / परियोजना में संपूर्ण स्थान पर कस्टम त्रुटियों का उपयोग होता है, तो आपको मूल रूप से इसे हर जगह परिभाषित करने की आवश्यकता होगी, या कम से कम कहीं:

  1. पहली बार में त्रुटि वर्ग को परिभाषित करें
  2. स्क्रिप्ट में जहां आप इसे फेंक रहे हैं
  3. स्क्रिप्ट में जहां आप इसे पकड़ रहे हैं

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

इसके अलावा, अगर यह गलत है तो कृपया मुझे बताएं क्योंकि मैंने अभी हाल ही में ऐसा करना शुरू किया है

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