Javascript 使用RequireJS在单例和原型范围之间切换

Javascript 使用RequireJS在单例和原型范围之间切换,javascript,dojo,singleton,requirejs,Javascript,Dojo,Singleton,Requirejs,Spring有一个非常有用的选项,即我定义一个bean,我定义一个范围。如果是单例,则只创建一个实例。通过prototype,每次需要bean时,都会创建一个新实例 RequireJS默认提供单例,因此使用这样简单的模块: Singleton.js 定义([],函数(){ console.log('实例初始化') 变量项=[] 变量单例={ getItems:function(){ 退货项目 }, setItems:函数(newItems){ 项目=新项目 }, 附加项:功能(项目){ 项目。推

Spring有一个非常有用的选项,即我定义一个bean,我定义一个范围。如果是单例,则只创建一个实例。通过prototype,每次需要bean时,都会创建一个新实例

RequireJS默认提供单例,因此使用这样简单的模块:

Singleton.js
定义([],函数(){
console.log('实例初始化')
变量项=[]
变量单例={
getItems:function(){
退货项目
},
setItems:函数(newItems){
项目=新项目
},
附加项:功能(项目){
项目。推送(项目)
}
};
返回单身;
})
以及用法:

require([“showcase/modules/Singleton”],函数(Singleton){
Singleton.addItem('item1')
console.log(Singleton.getItems())
})
需要([“showcase/modules/Singleton”],函数(Singleton){
Singleton.addItem('item2')
console.log(Singleton.getItems())
})
输出将是:

实例初始化 [“项目1”] [“第1项”、“第2项”]

如果我想使用prototype或singleton范围,是否可以以这样的方式定义和使用模块,即我可以在模块定义中切换?因此,在我的情况下,在不改变用法的情况下,我会得到:

实例初始化 [“项目1”] 实例初始化 [“项目2”]


我使用的是来自Dojo的RequireJS,只是为了防止语法差异。首先,问题是,当您使用AMD加载程序导入模块时,实际上会得到一个实例,但是第二次导入相同的模块时,实际上会返回相同的实例(问题1)

为了克服这个问题,您应该使用工厂设计模式来获取实例,并将单例对象转换为可以实例化的类(问题2)。您的工厂可以有一个名为
getInstance()
的方法,该方法接受一个
boolean
参数,可以在singleton/prototype之间切换

因此,如果不改变你的用法,你将无法做到这一点,因为我刚才提到的问题。我(通过工厂)能想到的最佳解决方案是:

Singleton.js
定义([],函数(){
log(“实例初始化”);
//独生子女班
var Singleton=function(){
此参数为.items=[];
this.getItems=函数(){
归还此物品;
};
this.setItems=函数(newItems){
this.items=newItems;
};
this.addItem=函数(项){
此.items.push(item);
}
};
//工厂
变量工厂={
singletonistance:new Singleton(),
getInstance:函数(/**Boolean*/isSingleton){
如果(isSingleton==真){
返回此.singletonistance;
}否则{
返回新的Singleton();
}
}
};
返回工厂;
});
用法(单例) 用法(多个实例) 如果你对一个完整的例子感兴趣,它就在上面

最终,您可以将工厂包装为插件,这样您就可以实际执行以下操作:

require([“app/Object!singleton”,“app/Object!prototype”],function()){
});

然而,我不知道RequireJS是否也支持这一点(如果我理解得很好,这应该是两款AMD装载机的通用故事)。

你检查wire.js()了吗?是的,我可以通过将SingletonFactory作为函数返回等方式来改进它。我想知道是否有一种内置方式来实现这一点。据我所知:没有。主要问题是AMD loader实际上从未两次获取同一个模块,而是重复使用该模块。因此,在单例/新实例之间的切换只能在“主代码”中实现。唯一的例外是插件,但是我不知道RequireJS是否支持插件。但即使这样,仍然需要一些额外的代码(编写工厂)。
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(true);
  Singleton.addItem('item1');
  console.log(Singleton.getItems());
});
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(true);
  Singleton.addItem('item2');
  console.log(Singleton.getItems());
});
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(false);
  Singleton.addItem('item3');
  console.log(Singleton.getItems());
});
require(["app/Singleton"], function(singletonFactory){
  var Singleton = singletonFactory.getInstance(false);
  Singleton.addItem('item4');
  console.log(Singleton.getItems());
});