使用`module`作为命名空间

时间:2016-04-06 02:32:16

标签: javascript node.js

我一直在使用我的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关键字} 方法。我从未见过这种模式在其他地方使用过,所以我想知道我是否遗漏了一些不太理想的东西。

思想?

2 个答案:

答案 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对象而不是函数。