所谓单列模式就是,一个类的所有实例共享一个对象。在强类型语言,如c++中也常用这种设计模式,用来在不同的地方操作同一个数据。
- 比较简单的写法如下:
function SingLeton(title){
this.title = title
this.instance = null
}
SingLeton.getInstance = function(title){
if(!this.instance){
this.instance = new SingLeton(title);
}
return this.instance;
}
var in1 = SingLeton.getInstance("instance1")
var in2 = SingLeton.getInstance("instance2")
console.log(in1 === in2) //true
用到了闭包,instance初始为null,instance为空的的时候返回一个新实例,不为空时返回保存的实例,保证所有的实例都为同一个,很有意思的写法
但是上面的写法有个弊端就是,写法比较别扭,不语义化,因为coder习惯了用new关键字来实例化对象,一般人也不知道要用SingLeton.getInstance("instance1")的语法来实例化对象,换句话说就是不‘国际化’。
- 改进下:
var instance = null;
function F(title) {
this.title = title;
}
function SingLeton(title){
if(!instance){
instance = new F(title);
}
return instance;
}
const f1 = new SingLeton('f1')
const f2 = new SingLeton('f2')
console.log(f1 == f2)
但是instance是全局变量 ,这样不好看,很容易被篡改,所以闭包优雅一波:
const SingLeton = (function(){
var instance = null;
function F(title) {
this.title = title;
}
function SingLeton(title){
if(!instance){
instance = new F(title);
}
return instance;
}
return SingLeton;
})()
const f1 = new SingLeton('f1')
const f2 = new SingLeton('f2')
console.log(f1 == f2) //true
console.log(f1.title) //f1
console.log(f2.title) //f1
改造后,仅仅暴露了我们需要的SingLeton变量,也用了new操作符,语义化很好。