乐趣区

设计模式用JavaScript实现单例模式

《JavaScript 设计模式与开发实践》的学习笔记
设计模式 - 用 JavaScript 实现单例模式

说明

定义:保证一个类仅有一个实例, 并提供一个访问它的全局访问点。
使用场景:全局缓存、Windows 对象、登录浮窗等
关键:用一个变量来标志是否已经为某个类创建对象,没有则创建,有则返回这个对象

标准单例模式

代码实现:
javascript code

/**
 * 标准单例模式
 * 缺点是使用者必须知道这是个单例类,本来可以直接 new xxx,现在变成了 xxx.getInstance
 */
var Singleton = function (name) {
  this.name = name
  this.instance = null
};
Singleton.prototype.getName = function () {alert(this.name)
}
Singleton.prototype.getInstance = function (name) {if(this.instance!==null){this.instance = new Singleton(name)
  }
  return this.instance
}

透明单例模式

javascript code

/**
 * 利用闭包和 IIFE 实现了透明单例模式
 * 但违反了单一职责原则
 * 缺点是,当不再需要单例时,需要改写构造函数
 */
var CreateDiv = (function() {
  var instance
  var CreateDiv = function(html) {if (instance) {return instance}
    this.html = html
    this.init() // 执行 init 方法
    return (instance = this) // 保证只有一个一个对象
  }
  CreateDiv.prototype.init = function() {var div = document.createElement('div')
    div.innerHTML = this.html
    document.body.appendChild(div)
  }
  return CreateDiv
})()

用代理实现的单例

javascript code

/**
 * 代理实现单例
 * 将负责管理单例的逻辑移到 proxySingletonCreate
 */
var CreateSpan = function(html) {
  this.html = html
  this.init()}
CreateSpan.prototype.init = function() {var span = document.createElement('span')
  span.innerHTML = this.html
  document.body.appendChild(span)
}

var proxySingletonCreate = (function() {
  var instance
  return function(html) {if (!instance) [(instance = new CreateSpan('test'))]
    return instance
  }
})()

创建单例的通用方法

由上可以看出,创建单例的核心即为使用一个变量表示这个对象是否被创建,即:
javascript code

var instance
if(!instance) {instance = xxx}

具体代码实现即为:
javascript code

/**
 * 创建单例的抽象方法
 * @param {function} fn 
 */
var getSingle = function(fn) {
  var result
  return function() {return result || (result = fn.apply(this, arguments)) 
  }
}
退出移动版