node.js标准模块的全局变量?

ajs*_*sie 55 javascript module global-variables shared-libraries node.js

我知道全局变量很糟糕.

但是,如果我使用节点的模块"UTIL"在我的框架40个文件,是不是更好,只是声明它像一个全局变量:

util = require('util');
Run Code Online (Sandbox Code Playgroud)

在index.js文件而不是在40个文件中写入该行?

因为我经常在每个文件中使用相同的5-10模块,这将节省大量的时间,而不是复制粘贴所有的时间.

在这种情况下DRY不好吗?

Rob*_*ett 102

你可以有一个共同的模块.

common.js:

Common = {
  util: require('util'),
  fs:   require('fs'),
  path: require('path')
};

module.exports = Common;
Run Code Online (Sandbox Code Playgroud)

app.js:

var Common = require('./common.js');
console.log(Common.util.inspect(Common));
Run Code Online (Sandbox Code Playgroud)

  • 这造成了不必要的依赖.2.它节省很少或创建更多的打字,因为现在你要么"Common.x.whatever"而不是"x.whatever"每个地方你使用"什么"或你用"var x = Common.x"代替它就像"var x = require(...)"一样,但如果你还不知道"x"是什么,那就不太清楚了.3.重构"x"的使用现在强制搜索Common.x和require("x"),因为你无法确定每个人都使用了Common.x. 如果你使用它那么多,为什么不只是制作一个片段"rutil> tab"? (19认同)
  • @Kato:这样比较好(实际上很出色),因为您现在不必在每个文件中包含10个模块,而只需包含一个模块。正如您所说,它们已被缓存,因此绝对没有过热。 (2认同)

Tor*_*amo 43

每个模块都应该是独立的.在每个模块的第一个之后,要求不会花费任何费用.

如果您想单独测试一个模块怎么办?您会遇到很多问题,因为它无法识别您的应用中的某些"全局"要求.

是的,即使在这种情况下,全局变量也很糟糕.Globals几乎总是毁灭:可测试性,封装和易维护性.

更新的答案2012年1月

global对象现在是每个模块内部的全局对象.因此,每次在模块内部分配全局变量(无范围)时,它都会成为global该模块对象的一部分.

global因此,该对象仍然不是全局的,不能这样使用.

2012年12月更新

global对象现在具有应用程序中的全局范围,可用于存储需要从所有模块访问的任何数据/功能.

  • @TorValamo这似乎不正确,我刚刚做了一个测试.无论你在一个模块中分配给```global.something```,都可以从另一个模块访问.因此```global```包含进程(=应用程序)全局变量,而不是模块全局变量,而```global```是所有会话的相同对象.至少那是它对我有用的方式.我可以问你为什么说```global```是模块的本地?你做过测试吗?如果是,那么测试是什么? (3认同)
  • @TorValamo确实有点令人困惑.他们只用了一行来说出```global```是什么,让我们解释它是如何工作的,然后3行咆哮为什么需要它.仍然[这里](http://nodejs.org/api/globals.html#globals_global_objects)他们说:"这些对象在所有模块中都可用.其中一些对象实际上并不在全局范围内,而是在模块范围内..."和[here](http://nodejs.org/api/globals.html#globals_global):"global:{Object}全局命名空间对象." ......无论如何,案件结束,再次更新答案的时间:)你还是我应该? (2认同)
  • @esp随时更新它,你似乎有比我更多的最新信息;) (2认同)

sum*_*tix 25

global.util = require('util');
Run Code Online (Sandbox Code Playgroud)

节点文档中有关于全局对象的部分.

但是,应谨慎使用全局变量.通过向全局空间添加模块,可以降低可测试性和封装性.但是有些情况下使用这种方法是可以接受的.例如,我将函数和对象添加到全局命名空间以在我的单元测试脚本中使用.


Dus*_*ham 21

我对这个帖子中的答案感到困惑.

我能做到这一点......

文件:test.js

global.mytest = {
    x: 3,
    y: function() { console.log('Works.'); }
};
Run Code Online (Sandbox Code Playgroud)

文件:test2.js

console.log('Does this work?');
mytest.y();
Run Code Online (Sandbox Code Playgroud)

文件:server.js

require('test.js');
require('test2.js');
Run Code Online (Sandbox Code Playgroud)

它似乎可以解决所需的问题.第一个要求将mytest对象放入全局范围,然后第二个要求可以访问该对象而不需要任何其他限定符.

我试图解决这个问题(这使我从谷歌搜索中找到了这个帖子),我想发布一些似乎对我有用的东西.也许自最初答案以来情况发生了变化.