在Node.js模块中,全局对象是什么?

3
我知道在Node中,每个模块都有一个本地作用域,除非明确导出,否则在模块内定义的变量不会逃逸到全局范围。
我想知道的是,当我在一个模块文件中声明以下变量时,这个变量定义在哪个全局对象上?
var obj = {};
// In browser, this is defined on window.obj
// How about in the node?

一条语句global是用作本地全局范围的对象,但以下测试代码失败:

a = 1
console.log global.a
// undefined

那么模块的全局变量是什么呢?


如果您正在使用新版本(可能是0.8之后)的Node进行工作,则“global”似乎可以正常工作。在0.6.2中,我似乎是通过Ubuntu 12.04获得的,它不起作用。 - Pointy
我实际上还没有机会玩Node.js,仍在等待一些空闲时间。:)但是出于兴趣,如果您获取以下代码返回的值会发生什么?var glob = (function(){return this;})(); - 在基于浏览器的JS世界中,对于大多数环境,这将返回Window对象。 - Pebbl
@Pointy 我正在使用 0.8.10.6.19,但两者都无法通过上述代码。 - steveyang
嗯,我不是很“懂”Node;我克隆了git存储库,那显然是“0.9.0-pre”或类似的版本。 - Pointy
2个回答

1

事实上,Node 中有一个全局对象,它被简单地称为 global。您可以向其分配属性并像任何其他对象一样访问这些属性,您可以跨模块执行此操作。但是,直接访问它(在一个模块中使用global.foo=bar,在另一个模块中使用baz=global.foo)是访问它的 唯一 方式。未经限定的变量名称从不会自动解析为其属性,就像浏览器环境中未经限定的变量名称将解析为window.somethingOrOther

在 Node 中,每个模块在一个立即函数调用内概念化包装起来,因此未经限定的名称表示本地变量并具有模块级作用域。


0

再编辑 我快要得出结论了,在一个 Node 模块中,你 不能 获得对全局对象的引用。你真的不应该需要这样做;我认为这就是模块机制的全部意义。你导入你所需的,导出你选择的。

在 Node 中是否有全局对象是一个有趣的问题,我想。我知道在 Rhino 中肯定有;在从 Java 容器中提供给 Rhino 的代码周围没有隐式包装函数。通过 Java ScriptEngine 机制(以及可能是来自“裸”Rhino中的 Mozilla API),有办法将符号推入全局上下文中,以使它们作为全局对象属性对 JavaScript 可见。

哇,这变得复杂了 好像 Node.js 的世界正在发生变化。我上面写的对于 Node 0.6.2 是正确的,但是在我刚刚做的 0.9.0-pre 版本中确实有一个名为 "global" 的对象,它的行为几乎类似于浏览器中的全局对象。


以下内容适用于浏览器、Rhino和其他类似的上下文环境。
在全局环境中,你可以使用 this。如果需要一个名称,你可以给它一个。
var global = this;

var obj = "Hi!";

global.obj = "Bye"; // sets "obj"

一个(有点)常见的习惯是将你的代码包装在一个函数中,以保护全局命名空间。
(function( global ) {
  // everything
})( this );

注意:我不是Node的专家,所以可能存在一些在该文化中新兴的习语。

编辑——我想到了一个问题,如果Node确实将代码从文件中评估为函数,并且它没有从全局上下文中传递this,那么我认为就没有办法“找到”它。如果你使用"use strict"(你应该这样做),那么这并不重要,因为你无法真正干扰全局上下文。


2
已经没有标准的全局变量设置了吗?我知道Node会自动将你的模块包装在(function () {})()中,以保护代码不会污染全局作用域。 - steveyang
就像我说的那样,我不是一个 Node 人,所以我不能确定。你可以查找全局对象的属性,其值为相同的对象,然后检查名称 :-) - Pointy
这可能是让我真正尝试使用Node的东西 :-) - Pointy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接