使用`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
文件,它将返回该对象,而不是函数。