2016-01-23 52 views
2

Node.js似乎使用不同的规则将变量附加到global对象,无论这是在REPL还是在脚本中完成的。关于Node.js中的全局变量

$ node 
> var a = 1; 
undefined 
> a 
1 
> global.a 
1 
> a === global.a 
true 

如图中REPL工作时,声明一个变量与上面var创建与global对象上该变量的名称的新属性。

然而,这似乎并没有在脚本的情况:

// test.js 

var a = 1; 
console.log(a); 
console.log(global.a); 
console.log(a === global.a); 

让我们运行脚本:

$ node test.js 
1 
undefined 
false 

这究竟是为什么?

回答

5

当脚本运行时,它被包装在一个模块中。脚本中的顶级变量位于模块函数内部,不是全局变量。这是node.js如何加载和运行脚本,无论是在初始命令行上指定还是使用require()加载。

在REPL中运行的代码不包含在模块函数中。

如果您希望变量是全局变量,请将它们专门分配给global对象,这可以在脚本或REPL中使用。

global.a = 1; 

全局变量通常在node.js中被忽略。相反,通过模块构造函数或其他模块方法传递对它们的引用,需要在特定模块之间共享变量。


当加载在node.js的一个模块,该模块的代码被插入到一个函数包装这样的:

(function (exports, require, module, __filename, __dirname) { 
    // Your module code injected here 
}); 

因此,如果在顶层声明变量a模块文件,代码最终会被node.js中这样执行:

(function (exports, require, module, __filename, __dirname) { 
     var a = 1; 
}); 

从这里,你可以看到a变量实际上是一个地方变量在模块函数包装器中,不在全局范围中,所以如果你想在全局范围中使用它,那么你必须将它分配给全局对象。

+0

足够清楚,我使用。 –

0

Node.js中没有window,但有另一个最高的对象叫做global

无论您在一个模块中指定给global.something的任何内容都可以从另一个模块访问。

例子:

app.js

global.name = "myName" 

现在你可以从任何模块

得到myController的的global.name。JS

console.log(global.name); // output: myName 

anotherModule.js

console.log(global.name); // output: myName 

现在当你在一个模块声明一个变量var i=0;是它可在所有的模块?不!

因为您的所有项目代码都被包装在模块下,所以在REPL上它没有。这是最高的水平。这就是为什么REPL变量变成全局的原因。

所以如果你想用全局的工作,你必须与global前缀

global.a = 1; 
console.log(global.a);