我一直在使用我的node.js模块中的模式,这对我来说是显而易见的,我认为它一定有问题,或者我会看到更多的人这样做。为了保留模块全局的私有变量,我只需将它们作为属性附加到模块对象上。像这样:
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)
}
}
...因为在第二个示例中,您需要在文件顶部搜索var someClient
,以确保在var
内有意省略init
关键字} 方法。我从未见过这种模式在其他地方使用过,所以我想知道我是否遗漏了一些不太理想的东西。
思想?
答案 0 :(得分:4)
我想到了一些可能的缺点。
1)技术上可以在模块外部访问和修改这些属性,但仅限于在模块外部提供对模块本身的引用。通过自己的导出使模块可用的东西(module.exports = module;
是最简单的例子)会暴露它们。
2)您可能与内置属性或将来不存在的未来内置属性存在命名冲突(这会导致您的代码在node.js的未来版本中中断)。这可能是非常有问题的并且很难调试。目前,模块对象的内置属性为:children, exports, filename, id, loaded, paths,
和parent
。
因为在第二个例子中你需要在文件顶部搜索var someClient,以确保在init方法中故意省略var关键字。
如果这是原因,您可以使用不是module
的命名空间。例如,将var private = {};
添加到每个文件的顶部,然后使用private.someClient
代替module.someClient
。
同样'use strict';
以便意外遗漏var
是一个错误,而不是偶然的全局。
答案 1 :(得分:1)
<强>缺点强>
选项1:正如@paulpro在答案中所述,这种做法很容易与内置属性或未存在的未来内置属性发生命名冲突。
选项2:如果您错过var
关键字并在全球范围内公开someClient
。此外,您需要始终在文件顶部搜索var someClient。
<强>替代强>
由于JavaScript具有功能范围,因此最好定义函数中的所有内容。在函数中创建私有和公共成员。以下是可以遵循的设计模式:
'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;
})();
此处仅暴露的方法是附加到该对象的方法。其余的都是功能范围的私有。即使您错过了var
中的someClient
关键字,也无法访问该功能,如果您在顶部使用'use strict'
,则不会发生这种情况。
逻辑是第一次需要
xyz.js
文件时,它将返回that
对象而不是函数。