我正在运行Node.js v0.10.1
的以下问题(通过一个快速示例演示):
在交互式命令行中运行node时:
> global.require
{ [Function: require] . . . }
> require
{ [Function: require] . . . }
当运行以下script.js
时,我得到了意想不到的结果:
console.log(global.require); // 1.
console.log(require); // 2.
undefined // 1. `global.require` is undefined!
{ [Function: require] . . .} // 2. `require` by itself works however.
我删除了额外的代码,用...
表示。在本地运行它以查看实际显示的全部内容。
是什么导致了这种情况的发生?
Node.js包含一个repl模块,允许您创建自己的Read-Evaluate-Print-Loops(这就是repl
所代表的)。使用这个模块有一个函数start,您可以使用它来创建一个新的repl。
该函数接受一个options
对象,您可以在该对象中配置repl。其中一个选项叫做useGlobal
。根据该选项的文档,下面的句子是有效的:
如果设置为
true
,则repl将使用global
对象,而不是在单独的上下文中运行脚本。默认为false
。
现在,当你在交互模式下启动Node.js时,这基本上只是一个repl,就像你可以使用repl
模块为自己创建的那些一样。我猜(请注意这只是猜测!)Node.js的默认repl将useGlobal
设置为true
。
因此,您有一个global
对象,它反过来与全局命名空间完全相同。因此,您可以在全局命名空间中找到的所有函数,例如require
,都将再次在global
对象中找到。
一旦你在非交互模式下启动一个Node.js应用程序,没有repl,因此没有global
对象。
你明白了吗?
许多全局变量通常不在全局作用域或global
对象的成员中:
这些对象在所有模块中都可用。这些对象中的一些实际上不在全局作用域中,而是在模块作用域中——这将被注意。
这些是"全局变量"更多的是第二种解释:
- 在最顶层的范围。
- 当前本地作用域以外的可访问作用域。
同样,如require()
所述:
要求模块。请参阅模块部分。
require
实际上不是全局的,而是每个模块的局部。
管理交互模式的REPL模块有一个将提升到全局作用域的选项:
useGlobal
—如果设置为true
,则repl将使用global
对象,而不是在单独的上下文中运行脚本。默认为false
。