单例模式
单例模式的定义是:保证一个类只有一个实例,并提供一个访问它的全局访问点。比如说购物车,在一个商城中,我们只需要一个购物车,购物车在整个商城中是唯一的,不需要多次创建,即使多次点击购物车按钮,也不会生成多个购物车。
闭包预警:有对闭包不明白的同学,可以看这里。
让我们实现一个单例模式吧
var Singleton = function(name) {
this.name = name;
}
Singleton.getInstance = (function () {
var instance = null;
return function (name) {
if (!instance) {
instance = new Singleton(name);
}
return instance;
}
})()
var single1 = Singleton.getInstance('张三');
var single2 = Singleton.getInstance('李四');
console.log(single1 === single2); // 输出true
我们主要看一下Singleton.getInstance
方法,其中将变量instance
作为一个标志,来确认是否创建过Singleton
对象。如果没有就创建一个Singleton
对象,反之则返回之前创建过的对象。
这样我们创建Singleton
对象的时候,就得使用Singleton.getInstance
方法,而不是使用new
关键字来创建对象。如果想使用new
关键字的话,可以这样写。
使用代理类来实现单例模式
var Singleton = function(name) {
this.name = name;
}
var ProxySingleton = (function () {
var instance = null;
return function(name) {
if (!instance) {
instance = new Singleton(name);
}
return instance;
}
})()
var single1 = new ProxySingleton('张三');
var single2 = new ProxySingleton('李四');
console.log(single1 === single2); // 输出true
我们将管理单例的逻辑放入ProxySingleton
这个代理类中,从而使Singleton
变成一个普通的类或者构造函数。这样我们就可以通过new
关键字来创建对象。
创建对象和管理单例逻辑职责分离
var createObj = function(name, age) {
return {
name: name,
age: age
}
}
var getSingle = function(fn) {
var instance = null;
return function () {
return instance || (instance = fn.apply(this, arguments));
}
}
var CreateFn = getSingle(createObj);
var obj1 = CreateFn('张三', 18);
var obj2 = CreateFn('李四', 19);
console.log(obj1 === obj2); // 输出true
这里createObj
方法负责创建对象和处理内部逻辑,getSingle
方法只负责管理单例的逻辑。这样在创建各种单例对象的情况下,使用更加灵活。也符合单一职责的开发原则。
单例模式的使用场景
单例模式的使用场景非常广泛,这里举几个