gpt4 book ai didi

javascript - 是否可以将全局范围注入(inject)到 ES6 中的实例化类中,也就是单例?

转载 作者:行者123 更新时间:2023-11-30 15:18:29 25 4
gpt4 key购买 nike

首先我需要道歉,因为这里面会有很多代码,这会使这个问题变得臃肿。但是我认为这将有助于更好地理解我的问题。

假设我有这个给定的 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');
}

};

如您所见,它用于动态加载模块,效果非常好。

我的问题是动态加载其他模块的 MainModule 无法在模块之间共享它自己的全局范围,或者至少我不知道如何共享。我很清楚这很复杂,因为我的 MainModuleModuleToBeLoaded 在不同的文件中。

例如,我的 MainModule 的全局范围内有一个 LoggerClass:

// 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。一个可能的解决方案是更改 ModuleToBeLaoded 中的 constructor。像这样:

  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);

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

我想实现的是ES6中已知的模式singelton pattern。有关更多信息,请查看此维基页面:https://en.wikipedia.org/wiki/Singleton_pattern


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

问候,巨人

最佳答案

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

您可以注意到,根据 LoggerClassthis.instanceData,实例是相同的

删除注释以使代码更简洁

关于javascript - 是否可以将全局范围注入(inject)到 ES6 中的实例化类中,也就是单例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44129366/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com