单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。
最基本的单例模式——对象字面量
对象字面量可以包含大量的属性和方法,将这些方法和属性组织在一起
- 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();