node.js 전역 변수?


208

나는 여기에 물었다 : node.js는 상속이 필요합니까?

var를 생략하여 변수를 전역 범위로 설정할 수 있다고 들었습니다.

이것은 나를 위해 작동하지 않습니다.

즉 :

_ = require('underscore');

필수 파일에서 _을 사용할 수 없습니다. Express로 설정하고 app.set다른 곳에서도 사용할 수 있습니다.

누군가 이것이 작동해야한다고 확인할 수 있습니까? 감사.


위의 줄은 어디에 있습니까?
Jan Hančič

3
이전 질문에 대한 답변이 효과가 없다면 새로운 질문을 시작해서는 안된다고 생각합니다. 대신 주석을 추가하고 허용 된 태그를 제거하십시오.
alienhard

5
편집하면 현재 활성화 된 질문 목록에 나타납니다.
MAK

3
사용하십시오 exports. 훨씬 낫다.
Emmerman

1
"엄격한 사용"을 가지고 있기 때문에 작동하지 않을 수 있습니다. 파일 상단에. 그것은 나를 위해 그렇게 작동합니다.
Geza Turi

답변:


237

다음 global과 같이 사용할 수 있습니다 .

global._ = require('underscore')

28
좀 더 자세한 정보를 제공해 주시겠습니까? 이 부분은 자바 스크립트 또는 노드의 일부입니까? 따르는 것이 좋은 패턴입니까? 에서와 같이해야합니까 아니면 익스프레스 세트를 사용해야합니까? 감사합니다
Harry

4
이전 의견이 잘못되었습니다. 브라우저 window에서 전역 객체입니다. document의 속성입니다 window.
위즈

77
이것은 따라야 할 좋은 패턴이 아닙니다. 이러지 마 모듈을 분리하기 위해 'require'를 사용하는 규칙은 잘 알려져 있습니다. 당신은 대담한 이유없이 그것을 위반해서는 안됩니다. 아래 내 답변을 참조하십시오.
Dave Dopson

일반적으로 전역은 피해야하지만 실제로 사용하려면 아래의 세 문장은 모두 동등하며 var를 전역 범위에 할당합니다. GLOBAL._ = require ( 'underscore'); global._ = 필요 ( '밑줄'); _ = 요구 ( '밑줄');
metaColin

프로젝트가 조금 커지기 시작하면 유지하기가 악몽이 될 것입니다. 내 접근 방식을 살펴보십시오.
Oliver Dixon

219

노드에서 "global"또는 "GLOBAL"오브젝트를 통해 글로벌 변수를 설정할 수 있습니다.

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;

위의 코드에서 "this"는 전역 컨텍스트입니다. 공통 JS 모듈 시스템 (노드가 사용하는)에서 모듈 내부의 "this"객체 (예 : "your code")는 전역 컨텍스트가 아닙니다. 이를 증명하기 위해 아래에서 "this"객체를 뿜어 낸 다음 거대한 "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');합니다. 예, Java에서와 마찬가지로 밑줄을 사용하는 모든 단일 파일 에서이 작업을 수행 import com.foo.bar;합니다. 이렇게하면 파일 간의 연결이 '명시 적'이므로 코드가 수행중인 작업을 쉽게 파악할 수 있습니다. 약간 성가 시지만 좋은 일입니다. .... 설교입니다.

모든 규칙에는 예외가 있습니다. "GLOBAL._"을 설정해야하는 정확히 하나의 인스턴스가 있습니다. 기본적으로 JSON 인 "config"파일을 정의하는 시스템을 만들고 있었지만 좀 더 융통성있게하기 위해 "JS로 작성"되었습니다. 이러한 구성 파일에는 '필수'문이 없었지만 밑줄 (ENTIRE 시스템은 밑줄 및 밑줄 템플릿로 표시됨)에 액세스하기를 원했기 때문에 "config"를 평가하기 전에 "GLOBAL._"을 설정했습니다. 예, 모든 규칙에 어딘가에 예외가 있습니다. 그러나 당신은 타당한 이유가 있고 "나는 '필수'를 입력하는 데 지쳐서 컨벤션을 깨고 싶다."


7
GLOBAL 사용의 단점은 무엇입니까? 왜 대담한 이유가 필요한가요? 결론은 내 앱이 작동한다는 것입니다.
trusktr

26
궁극적으로, 그렇습니다, 당신이 발송하는 경우, 그게 전부입니다. 그러나 특정 관행은 "모범 사례"라고하며,이를 준수하면 일반적으로 운송 가능성 및 / 또는 구축 한 제품을 유지할 수있는 가능성이 높아집니다. "좋은 관행"을 따르는 것이 프로젝트의 규모와 수명에 따라 중요합니다. 나는 한 번만 쓰고, 읽지 않았으며 (단일 개발자) 단일 프로젝트에 모든 종류의 불쾌한 해킹을 만들었습니다. 더 큰 프로젝트에서는 이러한 종류의 코너 절단으로 인해 프로젝트 추진력이 높아집니다.
Dave Dopson

48
특히 GLOBAL의 경우이 문제는 가독성 중 하나입니다. 프로그램이 전역 변수를 무차별하게 사용하는 경우 코드를 이해하려면 전체 앱의 동적 런타임 상태를 이해해야합니다. 이것이 프로그래머들이 세계적으로 열등한 이유입니다. 효과적으로 사용하는 데는 수십 가지 방법이 있다고 확신하지만, 주니어 프로그래머가 제품을 악용하여 악용 한 것으로 나타났습니다.
Dave Dopson

2
왜 구성을 일반 .js파일 에 넣고 구성을 require내보내기 전에 호출 할 수 없습니까?
Azat

4
@Jackie - en.wikipedia.org/wiki/Singleton_pattern . 당신이하고있는 일이 싱글 톤 패턴에 매핑된다면, 그것은 의미가 있습니다. 다음과 같은 경우 DB 연결은 싱글 톤일 수 있습니다. 4) 연결 객체는 스레드로부터 안전하며 많은 다른 호출자가 공유 할 수 있습니다.
Dave Dopson

78

GLOBAL 키워드를 사용하는 다른 솔루션은 프로젝트가 커질 때 유지 / 가독성 (+ 네임 스페이스 오염 및 버그)에 대한 악몽입니다. 나는이 실수를 여러 번 보았고 그것을 고치는 번거 로움이 있었다.

JS 파일을 사용한 다음 모듈 내보내기를 사용하십시오.

예:

globals.js

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

module.exports = Globals;

그런 다음이를 사용하려면 require를 사용하십시오.

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

12
나는 유니콘을 좋아하지 않지만 당신의 접근 방식을 좋아합니다. 감사.
Jonatas Walker

globals.domain그래도 변화 는 어떻습니까?
Fizzix

1
@iLoveUnicorns 답장을 보내 주셔서 감사합니다. 로그인 한 사용자 데이터를 저장하기 위해 주로 필요하기 때문에 'express-session'과 같은 대안을 살펴 보겠습니다.
Fizzix

11
내 의견으로는 이것이 더 나은 접근 방법이지만 전역을 만들지 않으며 질문에 대답하지 않습니다. 그것은 대안 적 접근법이며 항상 그들을 격려 할 것이지만, "이 스레드에 대한 유일한 정답입니다"와 같은 문장의 완고한 거칠기는 여기에 속하지 않습니다. stackoverflow.com/help/be-nice
Thor84no

2
이것은 더 나은 접근 방법 일 수 있지만 전역 네임 스페이스에있는 무언가에 의존하는 외부 작성 스크립트를 실행하려고하면 도움이되지 않습니다. IOW, 이것은 질문에 대답하지 않습니다.
binki

12

글로벌 네임 스페이스는 어떻습니까? global.MYAPI = {}

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

camilo-martin의 의견 후 편집 : 다른 모든 포스터는 관련된 나쁜 패턴에 대해 이야기합니다. 따라서 논의를 제쳐두고 변수를 전역 적으로 정의하는 가장 좋은 방법은 네임 스페이스를 사용하는 것입니다.

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


3
그게 뭐야 require! 네임 스페이스를 사용하는 것은 괜찮지 만 global.foo = global.foo || {}모든 파일이나 다른 것을 다 사용하지는 마십시오 . 네임 스페이스를 정의하는 파일이 필요합니다. 아이들을 위해 그것을하십시오.
Camilo Martin

@ camilo-martin Hi, 1) global.MYAPI._를 정의함으로써 모든 파일에서이를 정의 할 필요는 없습니다. 이것이 세계적인 이유입니다. 2) 이것은 아이들과 관련이 없습니다. 모든 사람들이 그것이 나쁜 패턴이라고 말하더라도, 그것은 프로그래머와 주어진 상황에 따라 언어 의이 능력을 어떻게 사용하는지에 달려 있습니다.
Igor Parra

2
예, 그러나 네임 스페이스의 일부 기능을 별도의 파일로 선언한다고 가정 해 보겠습니다. 그런 다음 객체를 사용하려면 파일이 필요합니다.이 객체는 이전 버전이며 CommonJS 및 CommonSense에도 적용되지 않습니다. 물건이 필요할 경우, 사용자 코드에 네임 스페이스가 필요하고 네임 스페이스에는 필요하지 않습니다. 참고 네임 스페이스에 대해 아무 말도하지 않습니다 . 누가 이유를 묻는 사람에 대한 규칙이 있습니다. 그리고 클라이언트 측에서는 노드가 가지고있는 것이 없습니다. 언급 한 링크는 노드가 아닌 브라우저에 관한 것이므로 특정 방식으로 (전역을 통해) 작업을 수행하고 있음을 참조하십시오.
Camilo Martin

1
슬프게도 당신이 게시 한 URL은 후행 슬래시를
제외한

10

전역 객체 만 사용할 수 있습니다.

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

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

5

글로벌을 설정하기 위해 global / GLOBAL 네임 스페이스를 사용하는 것은 나쁜 습관이며 이론 상으로는 ( 이론적 으로 작동 단어 임) 전혀 사용하지 않는다는 데 동의합니다 . 그러나 (예, 요원) 사용자 정의 오류 클래스를 설정하는 데 사용합니다.

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

global.MyError = [Function of MyError];

예, 금기 사항이지만 사이트 / 프로젝트가 전체에서 사용자 정의 오류를 사용하는 경우 기본적으로 어디서나 정의하거나 다음과 같이 어딘가에 정의해야합니다.

  1. 먼저 오류 클래스를 정의하십시오.
  2. 던지는 스크립트에서
  3. 당신이 그것을 잡는 스크립트에서

전역 네임 스페이스에서 사용자 지정 오류를 정의하면 고객 오류 라이브러리를 필요로하지 않아도됩니다. 해당 사용자 정의 오류가 정의되지 않은 경우 사용자 정의 오류가 발생하는 이미징.

또한, 이것이 잘못되면 최근에 방금 시작한 것으로 알려주세요.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.