node.js genel değişkenleri?


208

Burada sordum: node.js kalıtım gerektiriyor mu?

ve değişkenleri dışarıda bırakarak değişkenleri global kapsama ayarlayabileceğim söylendi.

Bu benim için işe yaramıyor.

yani:

_ = require('underscore');

_ Dosyasını gerekli dosyalarda kullanılabilir yapmaz. Ekspres ile ayarlayabilirsinizapp.set ve olsa başka bir yerde kullanılabilir var.

Birisi bunun çalışması gerektiğini doğrulayabilir mi? Teşekkürler.


Yukarıdaki çizginin neresi var?
Jan Hančič

3
Önceki sorunuzun cevabı işe yaramıyorsa yeni bir soru başlatmamanız gerektiğini düşünüyorum. Bunun yerine buraya bir yorum ekleyin ve kabul edilen etiketi kaldırın.
alienhard

5
Sadece düzenlemek, o anda aktif sorular listesinde görünmesini sağlar.
MAK

3
Kullanın exports. Çok daha iyi.
Emmerman

1
Belki işe yaramaz çünkü "katı kullanın"; tıklayın. Benim için böyle çalışıyor.
Geza Turi

Yanıtlar:


237

Şöyle kullanabilirsiniz global:

global._ = require('underscore')

28
Biraz daha bilgi verebilir misiniz lütfen? Bu JavaScript'in bir parçası mı yoksa düğümün bir parçası mı? Takip etmek iyi bir model mi? Olduğu gibi bunu yapmalı mıyım yoksa ekspres seti kullanmalı mıyım? Teşekkürler
Harry

4
Önceki yorum yanlış. Tarayıcıda, windowküresel bir nesnedir. documentbir malıdır window.
G-Wiz

77
Bu takip etmek için iyi bir desen DEĞİLDİR. Bunu yapma. Modülleri ayırmak için 'gereksinim' kullanma yöntemi iyi düşünülmüştür. İyi bir sebep olmadan onu ihlal etmemelisin. Aşağıdaki yanıtıma bakın.
Dave Dopson

Globallerden genellikle kaçınılmalıdır, ancak gerçekten kullanmak istiyorsanız. Aşağıdaki 3 ifadenin tümü eşdeğerdir ve genel kapsama bir değişken atayacaktır: GLOBAL._ = requir ('alt çizgi'); global._ = zorunlu ('alt çizgi'); _ = zorunlu ('alt çizgi');
metaColin

Projeniz biraz daha büyük olmaya başladığında, bu bir kabus haline gelecektir. Lütfen yaklaşımıma bir göz atın.
Oliver Dixon

219

Düğümde, global değişkenleri "global" veya "GLOBAL" nesnesi üzerinden ayarlayabilirsiniz:

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

ya da daha fazlası ...

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

Düğüm kaynağından, bunların birbirine takma olduğunu görebilirsiniz:

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

Yukarıdaki kodda "bu" genel bağlamdır. CommonJS modül sistemiyle (hangi düğüm kullanılır), bir modülün içindeki "bu" nesne (yani, "kodunuz") genel bağlam DEĞİLDİR. Bunun kanıtı için aşağıya "bu" nesneyi ve sonra dev "GLOBAL" nesnesini yazdığım yere bakın.

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: {} }
*/

** Not: "GLOBAL._" ayarı ile ilgili olarak, genel olarak yapmanız gerekir var _ = require('underscore');. Evet, bunu Java'da yaptığınız gibi alt çizgi kullanan her dosyada yaparsınız import com.foo.bar;. Bu, dosyalar arasındaki bağlantılar 'açık' olduğundan, kodunuzun ne yaptığını anlamayı kolaylaştırır. Hafif sinir bozucu, ama iyi bir şey. .... Bu vaaz.

Her kuralın bir istisnası vardır. "GLOBAL._" ayarlamam gereken tam olarak BİR örneğim vardı. Ben temelde JSON, ama biraz daha esneklik sağlamak için "JS'de yazılmış" "config" dosyaları tanımlamak için bir sistem oluşturuyordu. Bu tür yapılandırma dosyaları hiçbir 'gerektiriyor' ifadeleri vardı, ama onları alt çizgi erişimi olmasını istedim (ENTIRE sistemi alt çizgi ve alt çizgi şablonları üzerinde tahmin edildi), bu yüzden "config" değerlendirmeden önce "GLOBAL._" ayarlayın. Yani evet, her kural için bir yerde bir istisna var. Ama iyi bir nedeniniz olsa iyi olur ve sadece '' zorunlu '' yazmaktan yorulmam, böylece konvansiyondan kopmak istiyorum.


7
GLOBAL kullanmanın olumsuz yanları nelerdir? Neden iyi bir nedene ihtiyacım var? Sonuçta benim app çalışır, değil mi?
trusktr

26
sonuçta, evet, eğer gemi, önemli olan bu. Bununla birlikte, belirli uygulamalar "en iyi uygulamalar" olarak bilinir ve bunları takip etmek genellikle gönderim ve / veya inşa ettiğiniz şeyi sürdürme olasılığınızı artırır. "İyi uygulamaları" takip etmenin önemi, projenin büyüklüğü ve uzun ömürlülüğü ile artar. Ben bir kez yazma, asla okuma (ve "tek geliştirici") kısa ömürlü projelere her türlü kötü kesmek inşa ettik. Daha büyük bir projede, bu tür köşe kesimleri size proje momentumuna mal olur.
Dave Dopson

48
Özellikle, GLOBAL ile sorun okunabilirlik sorunlarından biridir. Programınız değişken olarak global değişkenler kullanıyorsa, kodu anlamak için tüm uygulamanın dinamik çalışma zamanı durumunu anlamam gerektiği anlamına gelir. Bu yüzden programcılar küresellerin temeli. Onları etkili bir şekilde kullanmanın düzinelerce yolu olduğundan eminim, ancak çoğunlukla genç programcılar tarafından ürünün hastalığına kötü muamele edildiğini gördük.
Dave Dopson

2
Yapılandırmaları dışa aktarmadan önce neden yapılandırmalarınızı normal bir .jsdosyaya koyup aramıyorsunuz require?
Azat

4
@Jackie - en.wikipedia.org/wiki/Singleton_pattern . Yaptığınız şey Singleton deseniyle eşleşiyorsa, o zaman mantıklı olabilir. DB bağlantıları aşağıdaki durumlarda tekil olabilir: 1) kurulum pahalı, 2) bağlantının yalnızca bir kez kurulmasını istiyorsanız, 3) bağlantı nesnesi uzun ömürlüdür ve ağ kesintileri durumunda başarısız bir duruma girmez, 4) bağlantı nesnesi iş parçacığı için güvenli / birçok farklı arayan tarafından paylaşılabilir.
Dave Dopson

78

GLOBAL anahtar sözcüğünü kullanan diğer çözümler, proje büyüdükçe bakımı / okunabilirliğini (+ ad alanı kirliliği ve hatalar) korumak için bir kabus. Bu hatayı birçok kez gördüm ve düzeltmekle uğraştım.

Bir JS dosyası kullanın, sonra modül dışa aktarmalarını kullanın.

Misal:

globals.js

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

module.exports = Globals;

Sonra bunları kullanmak istiyorsanız, requir kullanın.

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

12
Kesinlikle tek boynuzlu atları sevmiyorum ama yaklaşımınızı seviyorum. Teşekkürler.
Jonatas Walker

Değişmeye ne dersiniz globals.domain?
Fizzix

1
@iLoveUnicorns yanıtladığınız için teşekkürler. Esas olarak oturum açmış kullanıcı verilerini depolamak için ihtiyacım olduğu için 'hızlı oturum' gibi alternatiflere bakacağım.
Fizzix

11
Bence bu daha iyi bir yaklaşım olsa da, küreseller yaratmaz ve sorulan soruya cevap vermez. Bu alternatif bir yaklaşım ve ben her zaman teşvik ediyorum, ancak "Bu iş parçacığındaki tek doğru cevap bu" gibi ifadelerin sırf boğa gibi basitçe buraya ait değil. stackoverflow.com/help/be-nice
Thor84no

2
Bu daha iyi bir yaklaşım olabilir, ancak global ad alanında olan bir şeye dayanan harici olarak yazılmış komut dosyaları çalıştırmaya çalışıyorsanız, bu size yardımcı olmaz. IOW, bu soruya cevap vermiyor.
binki

12

Peki küresel bir isim alanına ne dersiniz? global.MYAPI = {}

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

Camilo-martin'in yorumundan sonra düzenleyin : Diğer tüm posterler ilgili kötü model hakkında konuşuyor. Bu tartışmayı bir kenara bırakmak, küresel olarak tanımlanmış bir değişkenin (OP'nin sorusu) en iyi yolu ad alanlarıdır.

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


3
Bunun requireiçin! Ad alanlarını kullanmak uygundur, ancak global.foo = global.foo || {}tüm dosyalara falan gitmeyin . Ad alanını tanımlayan dosyayı zorunlu kılın. Çocuklar için yap.
Camilo Martin

@ camilo-martin Merhaba, 1) global.MYAPI._ tanımlayarak tüm dosyalarda tanımlamanıza gerek yoktur, Global olmanızın nedeni budur. 2) Bu hiçbir şeyin çocuklarla olmaması gerekir. Her şey bunun kötü bir örüntü olduğunu söylese bile, programcıya ve dilin bu yeteneğini nasıl kullandığı durumuna bağlıdır.
Igor Parra

2
Evet, ancak ad alanının bazı işlevlerini ayrı bir dosyada bildirdiğinizi varsayalım. Sonra nesneyi kullanmak için bir dosyaya ihtiyacınız vardır, bu da geriye doğru ve CommonJS ve CommonSense'e karşı devam eder. Bir şeye gereksinim duyacaksanız, kullanıcı kodunun ad alanını gerektirmesini ve ad alanının gerektirmemesini sağlayın. Not İsim alanlarına karşı hiçbir şey söylemiyorum , sadece kimin kime sebep verdiğini anlatan sözleşmeler var. Ve istemci tarafında, düğümün sahip olduğu şey yoktur; bahsettiğiniz bağlantının belirli bir şekilde (global olarak) bir şey yaptığını görün, çünkü bu düğümle değil tarayıcıyla ilgilidir.
Camilo Martin

1
Ne yazık ki, gönderdiğiniz URL yalnızca eğik çizgiyi dışarıda bırakırsanız çalışır;)
Dirigible

10

Sadece global nesneyi kullanabilirsiniz.

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

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

5

Global / GLOBAL ad alanını küresel bir şey belirlemek için kullanmanın kötü bir uygulama olduğunu ve teoride hiç kullanmadıklarını kabul ediyorum ( teoride operatif kelime). Ancak (evet, etkin) Özel Hata sınıflarını ayarlamak için kullanıyorum:

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

global.MyError = [Function of MyError];

Evet, tabu burada, ancak siteniz / projeniz yer boyunca özel hatalar kullanıyorsa, temel olarak her yerde veya en azından bir yerde tanımlamanız gerekir:

  1. Error sınıfını en başta tanımlayın
  2. Attığınız senaryoda
  3. Yakaladığınız komut dosyasında

Genel hata alanındaki özel hatalarımı tanımlamak, müşteri hata kitaplığımı gerektirme zorluğunu ortadan kaldırıyor. Özel hatanın tanımsız olduğu yere özel bir hata atarak görüntüleme.

Ayrıca, eğer bu yanlışsa, lütfen bunu yeni yeni yapmaya başladığım için bana bildirin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.