我有以下脚本:
/* script.js */
var bar = "bar1";
function foo() {
console.log('this.bar: ' + this.bar);
console.log('global.bar: ' + global.bar);
}
foo();
运行node script.js
会返回:
this.bar: undefined
global.bar: undefined
但是,从节点命令行环境内部,再现相同的脚本会返回:
this.bar: bar1
global.bar: bar1
此外,如果我将变量声明从var bar = "bar1";
更改为global.bar = "bar1";
,则运行上述代码的两种方法都会返回:
this.bar: bar1
global.bar: bar1
有什么区别?运行脚本与在同一环境中重现脚本时,全局变量赋值是否有所不同?
答案 0 :(得分:4)
只是因为每个节点模块都包含在各种IIFE中,所以默认情况下你不在全局范围内。
我们可以在src/node.js
函数的NativeModule.require = function(id) {
// ...
var nativeModule = new NativeModule(id);
nativeModule.cache();
nativeModule.compile();
return nativeModule.exports;
};
中看到它发生。
compile
在跟踪之后,我们会调查NativeModule.prototype.compile = function() {
var source = NativeModule.getSource(this.id);
source = NativeModule.wrap(source);
var fn = runInThisContext(source, { filename: this.filename });
fn(this.exports, NativeModule.require, this, this.filename);
this.loaded = true;
};
:
wrap
NativeModule.wrap = function(script) {
return NativeModule.wrapper[0] + script + NativeModule.wrapper[1];
};
NativeModule.wrapper = [
'(function (exports, require, module, __filename, __dirname) { ',
'\n});'
];
看起来很相关,让我们看看它的作用:
if (self.useGlobal) {
result = script.runInThisContext({ displayErrors: false });
} else {
result = script.runInContext(context, { displayErrors: false });
}
如所怀疑的,它将您的模块代码包装在IIFE中,这意味着您不会在全局范围内运行。
另一方面,REPL NativeModule在全局范围内运行。在REPL代码之后是meh,但它基本上归结为by default:
{{1}}
这看起来与我无关。
答案 1 :(得分:3)
http://nodejs.org/api/globals.html
Node模块中的var内容将是该模块的本地内容。
我认为当你从文件中运行某些东西时,它被解释为节点的模块。如果在命令shell中执行,则在范围之上的变量将变为全局变量。