使用`module`作为命名空间

我一直在我的node.js模块中使用一个模式,这对我来说似乎是非常明显的,所以我认为一定有什么问题,或者我会看到更多的人这样做。 为了保持模块全局的私有variables,我只需将它们作为属性附加在模块对象上。 像这样:

module.exports = { init: function() { module.someClient = initializeSomethingHere() }, someMethod: function(done) { module.someClient.doSomething(done) } } 

这似乎比这样的东西更可取

 var someClient; module.exports = { init: function() { someClient = initializeSomethingHere() }, someMethod: function(done) { someClient.doSomething(done) } } 

…因为在第二个示例中,您需要在文件的顶部searchvar someClient ,以确保在init方法中省略var关键字是有意的。 我从来没有见过这种模式在其他地方使用,所以我想知道是否我错过了一些不理想的东西。

思考?

有几个可能的缺点,想到。

1)在技术上可以在模块之外访问和修改这些属性,但是只有在模块外部引用了该模块。 通过自己的输出( module.exports = module;是最简单的例子)使得模块可用的东西会暴露它们。

2)你可能会与内build属性或未来的内build属性(现在还不存在)相冲突(这会导致你的代码在未来版本的node.js中被破坏)。 这可能是非常有问题的,而且很难debugging。 目前模块对象的内build属性是: children, exports, filename, id, loaded, paths,parent

因为在第二个示例中,您需要在文件的顶部searchvar someClient,以确保在init方法中省略var关键字是有意的。

如果这是原因,你可以只使用一个不是module的命名空间。 例如通过添加var private = {}; 到每个文件的顶部,然后使用private.someClient而不是module.someClient

也是'use strict'; 所以var的意外遗漏是一个错误,而不是一个偶然的全局。

缺点

  • select1:这种做法很容易与内部财产或未来内部财产的命名冲突,因为@paulpro在他的回答中表示。

  • 选项2:如果您错过了var关键字并全局公开someClient 。 除此之外,您还需要始终在文件顶部searchvar someClient。

替代

由于JavaScript具有函数范围,因此最好在函数中定义所有内容。 在一个函数中创build私有和公共成员。 下面是一个可以遵循的devise模式:

 'use strict'; module.exports = (function(){ //private var someClient; //public properties var that={}; that.init = function() { someClient = initializeSomethingHere() }, that.someMethod: function(done) { someClient.doSomething(done) } //expose only the required methods return that; })(); 

这里只有暴露的方法是那些附着在那个对象上的方法。 而其余的function都是私有的。 即使你在someClient遗漏了var关键字,也不能在函数的外部访问,如果你在顶部使用'use strict' ,这种情况就不会发生。

逻辑是第一次当你需要xyz.js文件,它将返回该对象,而不是函数。