从脚本到命令行的节点中的全局variables赋值
我有以下脚本:
/* 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";
更改variables声明var bar = "bar1";
到global.bar = "bar1";
运行上述代码的两种方法都返回:
this.bar: bar1 global.bar: bar1
有什么不同? 当在同一个环境中运行一个脚本和一个脚本时,全局variables赋值是否有所不同?
只是因为每个节点模块都被包装在一个IIFE中,所以默认情况下你不在全局范围内。
我们可以在NativeModule函数中看到它发生在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});' ];
怀疑它把你的模块的代码包装在一个IIFE中,这意味着你不能在全局范围内运行。
另一方面, 默认情况下 ,REPL运行在全局范围内。 在REPL代码之后是meh,但基本归结为这一行 :
if (self.useGlobal) { result = script.runInThisContext({ displayErrors: false }); } else { result = script.runInContext(context, { displayErrors: false }); }
这看起来与我有关。
http://nodejs.org/api/globals.html
在Node模块内的var内容将是该模块的本地内容。
我认为,当你从文件运行的东西,它被解释为节点的模块。 如果你在命令行中执行,范围之上的variables将变成全局variables。