具有共享模块的类的多个实例
Multiple instances of a class with shared modules
我在运行一个类的多个实例时遇到了一些问题,同时使用 ES6 模块以获得更清晰的项目结构。
我将尝试在下面解释我的问题。我真正的项目更大,更复杂,但我以此为例。
版本 1
主.js
import App from './app';
let instance1 = new App,
instance2 = new App;
应用.js
import Layer from './layer'
import Element from './element'
class App {
constructor() {
this.layer = new Layer;
this.element = new Element;
}
addLayer() {
this.layer.addLayer();
}
addElement() {
this.element.addElement();
}
}
module.exports = App;
层.js
class Layer {
constructor() {
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
}
module.exports = Layer;
元素.js
class Element {
constructor() {
this.elements = [];
}
addElement(name) {
this.elements.push({
name: name
});
}
}
module.exports = Element;
现在我得到了一个独特的instance1
和instance2
实例,包含它自己的层和元素。当元素.js和层.js想要相互通信时,问题就来了。我无法import Layer from './layer'
insideelement.js而无需创建新实例,无法访问从应用程序内其他位置创建的图层。
版本 2
主.js
import App from './app';
let instance1 = new App,
instance2 = new App;
应用.js
import layer from './layer'
import element from './element'
class App {
addLayer() {
layer.addLayer();
}
addElement() {
element.addElement();
}
}
module.exports = App;
层.js
class Layer {
constructor() {
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
}
let layer = new Layer;
module.exports = layer;
元素.js
class Element {
constructor() {
this.elements = [];
}
addElement(name) {
this.elements.push({
name: name
});
}
}
let element = new Element;
module.exports = element;
在这种情况下,我可以从元素访问图层.js反之亦然,但它们也将在应用程序的两个实例之间共享,这不是我想要的。
这最初是一个单一的应用程序.js它包含所有内容并且运行良好,但随着项目的发展,它变得非常难以维护。但下面是我想要实现的示例。
应用.js
class App {
constructor() {
this.layers = [];
this.elements = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
addElement(name) {
this.elements.push({
name: name
});
}
}
module.exports = App;
有没有办法在这里两全其美?我已经考虑过为应用程序的每个实例创建一个商店,跟踪它自己的层和元素,但共享它的功能,但我不确定把它放在哪里以及如何在应用程序中传递对它的引用。
编辑
澄清一下,因为我在评论中得到了这个问题。实际上,这是一个更大的项目,其中包含许多不同的模块,这些模块以许多不同的方式相互交互。上面的最小版本仅用于这个问题,但这里有一些额外的部分作为层.js和元素.js之间交互的示例。
主.js
instance1.element.get('element1').addToLayer('background');
层.js
.addLayer(name) {
this.layers.push({
name: name,
elements: [],
add: (element) => {
this.elements.push(element);
}
});
}
元素.js
import layer from './layer';
...
.get(name) {
let el;
for(item in this.elements) {
if(item.name == name) {
el = item;
break;
}
}
return el;
}
.addElement(name) {
this.elements.push({
name: name,
addToLayer: (name) => {
let l;
for(item in layer.layers) {
if(item.name == name {
l = item;
break;
}
}
if(l) l.add(this);
}
});
}
在版本 1 中,layer.layers
在这里为空,因为我必须创建它的新实例。在版本 2 中,它可以正常工作,但应用程序的所有实例将共享相同的layer.layers
。
版本 1
应用.js
import Layer from './layer'
import Element from './element'
class App {
constructor() {
this.layer = new Layer(this);
this.element = new Element(this);
}
addLayer() {
this.layer.addLayer();
}
addElement() {
this.element.addElement();
}
}
module.exports = App;
层.js
class Layer {
constructor(app) {
this.App = app;
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
this.App.element.addElement(name); // Element method
}
foo() {
console.log('Hey you!!');
}
}
module.exports = Layer;
元素.js
class Element {
constructor(app) {
this.App = app;
this.elements = [];
}
addElement(name) {
// ...
this.App.layer.foo(); // I can talk with Layer class
}
}
module.exports = Element;
另请参阅 https://github.com/jonataswalker/es6-sample-project
几天里,我一直在解决同样的问题,并提出了一种不需要使用类的方法。
我的完整解决方案是针对需要为具有多个地图的仪表板实例化的地图控件。
免責聲明;这个解决方案不是我自己想出来的,而是使用了代码导师的建议。
主.MJS
import App from './app.mjs';
const instance1 = App();
const instance2 = App();
app.mjs
import Layer from './layer.mjs';
import Element from './element.mjs';
export default () => {
const app = {};
Layer(app);
Element(app);
return app;
}
layer.mjs/element.mjs
export default app => {
app.layers = [];
app.addLayer = name => {
app.layer.push({
name: name
})
}
}
此外,我
创建了一个lib.mjs文件,我将其与Webpack捆绑在一起并用作源库文件。在这里,导入实例构造函数"App"并将此函数分配给窗口对象。
这是一个 jsfiddle,我在其中导入捆绑库并创建两个映射实例。
lib.mjs
import App from './app.mjs';
window.App = App;
- 在requirejs中共享实例化对象
- 为什么原型允许多个实例共享变量
- 不需要的Javascript效果:原型在实例之间共享闭包
- Aurelia组件在其他视图模型中使用时不共享实例
- Dojo:小部件实例共享相同的变量
- 嵌套函数中的 JavaScript 实例共享
- 由表达式文本创建的正则表达式是否共享单个实例
- 将共享的“code_block”从 loc-A 移动到 loc-B,只有一个书面的“code_block”实例
- 为什么 PrototypeJS 类实例共享相同的属性
- 在同一控制器(ng-controller)的不同实例之间共享数据
- GWT:在同一模块的实例之间共享信息
- 具有共享模块的类的多个实例
- Javascript OOP - 多个实例共享相同的数据
- 指令实例共享Ajax结果,但我不希望它们共享
- 为什么基类的对象属性与子类的所有实例共享?
- 跨实例共享的Javascript对象属性
- Javascript OOP / Classes -多个实例共享相同的数据
- 无论如何,是否有让实例共享相同的函数但同时具有私有变量
- 私有成员——跨实例共享的Javascript变量
- 防止构造函数的多个实例共享相同的原型属性