我知道全局变量很糟糕。
但是如果我在我的框架中的40个文件中使用node的模块“util”,那么将它声明为全局变量并不是更好:
util = require('util');
在index.js文件中而不是在40个文件中写入该行?
因为我经常在每个文件中使用相同的5-10个模块,这样可以节省大量时间,而不是一直复制粘贴。
在这种情况下,DRY不是很好吗?
答案 0 :(得分:102)
你可以有一个共同的模块。
common.js:
Common = {
util: require('util'),
fs: require('fs'),
path: require('path')
};
module.exports = Common;
app.js:
var Common = require('./common.js');
console.log(Common.util.inspect(Common));
答案 1 :(得分:43)
每个模块应该是独立的。在每个模块的第一个之后,要求不会花费任何费用。
如果您想单独测试一个模块怎么办?您会遇到很多问题,因为它无法识别您的应用中的某些“全局”要求。
是的,即使在这种情况下,全局变量也很糟糕。 Globals几乎总是毁了:可测试性,封装性和易维护性。
更新的答案2012年1月
global
对象现在是每个模块中的全局对象。因此,每次在模块内部分配全局变量(无范围)时,它都会成为该模块的global
对象的一部分。
因此 global
对象仍然不是全局,并且不能这样使用。
2012年12月更新
global
对象现在具有应用程序中的全局范围,可用于存储需要从所有模块访问的任何数据/函数。
答案 2 :(得分:25)
global.util = require('util');
node documentation中有关于全局对象的部分。
但是,应谨慎使用全局变量。通过向全局空间添加模块,可以降低可测试性和封装性。但是有些情况下使用这种方法是可以接受的。例如,我将函数和对象添加到全局命名空间以在我的单元测试脚本中使用。
答案 3 :(得分:20)
我对这个帖子中的答案感到困惑。
我能够做到这一点......
文件:test.js
global.mytest = {
x: 3,
y: function() { console.log('Works.'); }
};
文件:test2.js
console.log('Does this work?');
mytest.y();
文件:server.js
require('test.js');
require('test2.js');
它似乎可以解决所需的问题。第一个要求将mytest对象放入全局范围,然后第二个要求可以访问该对象而不需要任何其他限定符。
我试图解决这个问题(这使我从Google搜索中找到了这个帖子),我想发布一些似乎对我有用的内容。也许自最初答案以来情况发生了变化。
答案 4 :(得分:0)
我已成功使用process
对象传递配置对象。虽然在理论上遇到了与上面提到的完全相同的问题(封装,可测试性等),但是当仅使用非状态修改属性(基本上具有基元的哈希表)时,它可以正常工作。
答案 5 :(得分:-3)
如果你将模块包装在块中(例如anon函数),你可以绑定到本地名称(通过参数或'var'),然后你想要任意长(可能是“包”标签)名称(如果你连此时需要全球化。)
例如,我的模块通常类似于:
;(function ($, $exp, other) {
$(...)
other.xyz()
$exp.MyExportedObject = ...;
})(jQuery, window, some_module.other_expression) // end module
我使用jQuery和noConflict,这是前者,后者表明你可以为任何表达式做这个 - 全局,需求,计算,内联,无论什么......这同样的“包装”方法可以用来消除所有(或几乎所有)“特殊命名”全局变量 - 全局变量必须存在于某个层次,但是,消除潜在冲突是一个非常大的胜利。