单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
最基本的单例模式——对象字面量
对象字面量可以包含大量的属性和方法,将这些方法和属性组织在一起
var Singleton = {
attribute1: true,
attribute2: 10,
method1: function() {
},
method2: function(arg) {
}
};
Singleton.attribute1 = false;
var total = Singleton.attribute2 + 5;
var result = Singleton.method1();
使用闭包
如果以后要扩展该对象,你可以添加自己的私有成员和方法,使用闭包将其封装这些变量和函数声明,只暴露你想暴露的public成员和方法。
var Singleton = (function() {
// Private members.
var privateAttribute1 = false;
var privateAttribute2 = [1, 2, 3];
// Private function
function privateMethod1() {
...
}
function privateMethod2(args) {
...
}
return { // Public members.
publicAttribute1: true,
publicAttribute2: 10,
publicMethod1: function() {
...
},
publicMethod2: function(args) {
...
}
};
})();
var singleton = Singleton();
singleton.publicMethod1();
惰性实例化
前面所讲的单例模式都有一个共同特点,单例对象都是在脚本加载时被创建出来,对于资源密集型的或配置开销甚大的单体,也许更合理的做法是将其实例化推迟到需要使用时才实例化。它最常用于那些必须加载大量数据的单体。惰性加载单体的特别之处在于,对他们的访问必须借助于一个静态方法。应该这样调用其方法:Singleton.getInstance().methodName()。getInstance()方法会检查单体是否已经被实例化,如果还没有,那么创建并返回其实例,如果单体已经实例过,那么将返回现有实例。
var Singleton = (function() {
var instanced;
function constructor () {
var privateAttribute1 = false;
var privateAttribute2 = [1, 2, 3];
function privateMethod1() {
...
}
function privateMethod2(args) {
...
}
return {
publicAttribute1: true,
publicAttribute2: 10,
publicMethod1: function() {
...
},
publicMethod2: function(args) {
...
}
};
}
return {
getInstance: function () {
if (!instanced) {
instanced = constructor();
}
return instanced;
}
};
})();
Singleton.getInstance().publicMethod1();