是否有可能将全局范围注入ES6又名单例中的实例化类?

首先,我需要道歉,因为这将会有很多代码,这将膨胀这个问题。 不过,我认为这将有助于更好地了解我的问题。

比方说,我给这个MainModule

 'use strict'; /** * Loads Module from given name. * @class {LoadModules} */ class LoadModules { constructor(moduleName) { // define Modulename. this.moduleName = moduleName; } /** * Initialize module. * @method init * @return {void} [nothing] */ init() { // Path Module. const path = require('path'); // Require Module from given Name. let ModuleToLoad = require(path.join(__dirname, 'Modules', this.moduleName, this.moduleName + '.js')); // Instatiate Module. ModuleToLoad = new ModuleToLoad(); // Start module. ModuleToLoad.init(); } } 

还有一个可以加载到MainModule模块:

 /** * This is a Module which can be loaded by the MainModule. * @class {ModuleToBeLoaded} */ module.exports = class ModuleToBeLoaded { constructor() { /** * Empty */ } /** * Initialize newly loaded Module. * @method init * @return {void} [nothing] */ init() { console.log('module Loaded'); } }; 

正如你所看到的,这是用来dynamic加载模块,这很好地工作。

我的问题是,我的MainModuledynamic加载其他模块不能共享自己的全球范围之间的模块,或者至less我没有弄清楚如何。 我很清楚,这是复杂的,因为我的MainModuleModuleToBeLoaded是在不同的文件。

例如我在我的LoggerClass的全局范围中有一个MainModule

 // This is in the global scope. const LoggerClass = new Logger(); /** * LoadModule class stuff comes after this. */ 

我希望所有的模块访问LoggerClass,就好像它们在全局范围内一样,而不是在每一个模块中一遍又一遍的定义。 作为一个例子,我将把ModuleToBeLoaded类中的console.log改为:

  /** * Initialize newly loaded Module. * @method init * @return {void} [nothing] */ init() { LoggerClass.log('module Loaded'); } 

所以基本上我在MainModule定义了Globals,我想在ModuleToBeLoaded的代码中访问这些Globals。 一个可能的解决scheme可能是更改ModuleToBeLaodedconstructor ModuleToBeLaoded 。 喜欢这个:

  constructor(LoggerClass) { // Here I can set LoggerClass internally. this.LoggerClass = LoggerClass; } /** * Initialize newly loaded Module. * @method init * @return {void} [nothing] */ init() { this.LoggerClass.log('module Loaded'); } 

这可以让我像这样实例化类:

 // Instatiate Module. ModuleToLoad = new ModuleToLoad(LoggerClass); 

这是正确的方法,还是有更好的其他解决scheme吗?

我想要实现的是ES6中已知的模式singelton pattern 。 欲了解更多信息,请看这个Wikipage: https ://en.wikipedia.org/wiki/Singleton_pattern


旁注:我在没有任何第三方库的NodeJS 7.10.0环境中。

问候,Megajin

LoggerClass.js这是你如何做单身(总是相同的实例)

 let instance; module.exports = function () { if (!instance) { instance = new LoggerClass(); } return instance; } class LoggerClass { constructor() { this.instanceData = Date.now(); } log() { console.log(`logging secret instance: ${this.instanceData}`); } } 

LoadModules.js

 const getLoggerClass = require('./LoggerClass'); module.exports = class LoadModules { constructor(moduleName) { this.moduleName = moduleName; } init() { const path = require('path'); // changed the require statement, to make it simpler let ModuleToLoad = require(path.join(__dirname, this.moduleName + '.js')); ModuleToLoad = new ModuleToLoad(getLoggerClass()); ModuleToLoad.init(); } } 

ModuleToLoad.js

 module.exports = class ModuleToBeLoaded { constructor(logger) { this.logger = logger; } init() { console.log('ModuleToBeLoaded module Loaded'); this.logger.log(); } }; 

ModuleToLoad2.js

 module.exports = class ModuleToBeLoaded { constructor(logger) { this.logger = logger; } init() { console.log('ModuleToBeLoaded2 module Loaded'); this.logger.log(); } }; 

演示

 > node > const LoadModules = require('./LoadModules'); > var load = new LoadModules('ModuleToLoad'); > var load2 = new LoadModules('ModuleToLoad2'); > load.init(); ModuleToBeLoaded module Loaded logging secret instance: 1495528699144 > load2.init(); ModuleToBeLoaded2 module Loaded logging secret instance: 1495528699144 

正如你可以注意到的,根据this.instanceDatathis.instanceData ,实例是一样的

删除注释以使代码更加简单

我发现你有一个单独的constructorinit很奇怪。 为什么不在构造函数中进行初始化?

无论如何,似乎正确的方法确实是将您的“全局”传递给您要加载的模块的构造函数或init。

如果你真的希望它是一个全局的,你可以将它添加到global名称空间。