是否有可能将全局范围注入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加载模块,这很好地工作。
我的问题是,我的MainModule
dynamic加载其他模块不能共享自己的全球范围之间的模块,或者至less我没有弄清楚如何。 我很清楚,这是复杂的,因为我的MainModule
和ModuleToBeLoaded
是在不同的文件。
例如我在我的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可能是更改ModuleToBeLaoded
的constructor
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.instanceData
的this.instanceData ,实例是一样的
删除注释以使代码更加简单
我发现你有一个单独的constructor
和init
很奇怪。 为什么不在构造函数中进行初始化?
无论如何,似乎正确的方法确实是将您的“全局”传递给您要加载的模块的构造函数或init。
如果你真的希望它是一个全局的,你可以将它添加到global
名称空间。