保证一个类仅有以一个实例,仅能被实例化/建立一次,并提供全局的访问点。javascript
单例模式是一种重要的设计模式,有些对象咱们只须要建立一个,好比浏览器的window对象,模态对话框。实现这种设计模式其实很简单,最重要的是在建立实例的时候,用一个标记变量判断实例是否已经建立。html
function Singleton(name){ this.name = name; this.instance = null; } Singleton.prototype.getName = function(){ console.log('name: ' + this.name); return this.name; } Singleton.getInstance = function(name){ if(!this.instance){ this.instance = new Singleton(name); } return this.instance; } var a = Singleton.getInstance('a'); var b = Singleton.getInstance('b'); alert(a === b);
点评:
该写法不透明,使用者必须知道用Singleton.getInstance
获取单例,而非经过更加通用的方法new xxx
方式。java
var CreateDiv = function(html){ this.html = html; this.init(); } CreateDiv.prototype.init = function(){ var div = document.createElement('div'); div.innerHTML = this.html; document.body.appendChild(div); } var SingletonDiv = (function(){ var instance; return function(html){ if(!instance){ instance = new CreateDiv(html); } return instance; } })() var a = SingletonDiv('yyh'); var b = SingletonDiv('yyh1');
点评:
使用代理类+普通的类,使得职责分明。普通类负责实现基本功能,代理类管理单例。CreateDiv能够直接生产一个实例,而加上代理,能够实现单例。有木有一种模块拼凑的快感,这就实现了低耦合。设计模式
在ES6中,能够使用static方法代替闭包存储单例。浏览器
class Singleton { constructor(name) { this.name = name; } static getInstance(name) { if(!Singleton.instance) { Singleton.instance = new Singleton(name) } return Singleton.instance; } getName() { return this.name; } } const singletonA = Singleton.getInstance('yyh1'); const singletonB = Singleton.getInstance('yyh2'); console.log(singletonA === singletonB); console.log(singletonA.getName() === singletonB.getName());
点评:ES6的静态方法,和闭包同样能在减小全局变量污染的同时,使标记变量更加长久的保存在内存中不被回收。闭包
// 负责建立DIV的基本功能 class CreateDiv { constructor(html) { this.html = html; this.init(); } init() { const div = document.createElement('div'); div.innerHTML = this.html; document.body.appendChild(div); } } // 负责管理单例 class ProxysingletonCreateDiv { constructor(htmlStr) { return ProxysingletonCreateDiv.getInstance(htmlStr); } static getInstance(name) { if(!ProxysingletonCreateDiv.instance) { ProxysingletonCreateDiv.instance = new CreateDiv(name) } return ProxysingletonCreateDiv.instance; } } const singletonC = new ProxysingletonCreateDiv('yyh1'); const singletonD = new ProxysingletonCreateDiv('yyh2'); console.log(singletonC === singletonD); singletonC.init(); singletonD.init();