记录一下学习过程。
标准的单例模式
/**
* 实现思路:用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的对象时,直接返回之前创建的对象
* 缺点:增加了类的"不透明性",使用者必须知道这是一个单例类,并且必须要通过getInstance()来获取对象。
*/
var Singleton = function(name) {
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function() {
console.log(this.name);
};
Singleton.getInstance = function(name) {
if (!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
};
var a = Singleton.getInstance('jack');
var b = Singleton.getInstance('lucy');
console.log(a === b);
透明的单例模式
/**
* 2.透明的单例模式
* 功能说明:在页面上创建唯一的div元素
* 缺点:CreateDiv的构造函数实际上负责了两件事情,创建对象和执行初始化init方法,不符合单一原则
*/
var CreateDiv = (function() {
var instance;
var CreateDiv = function(html) {
if (instance) {
return instance;
}
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function() {
var div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
return CreateDiv;
})();
var a = new CreateDiv('jack');
var b = new CreateDiv('lucy');
console.log(a === b);
用代理模式实现单例
//移除管理单例的代码
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 ProxySingletonCreateDiv = (function() {
var instance;
return function (html) {
if (!instance) {
instance = new CreateDiv(html);
}
return instance;
};
})();
var a = new ProxySingletonCreateDiv('jack');
var b = new ProxySingletonCreateDiv('lucy');
console.log(a === b);
惰性单例
/**
* 惰性单例指的是在需要的时候才创建对象实例。
*/
//基于类的单例
Singleton.getInstance = (function() {
var instance = null;
return function(name) {
if (!instance) {
instance = new Singleton(name);
}
};
})();
//这里的例子就不写了,
//思想就是把创建实例对象的职责和管理单例的职责分别放置在两个方法里,这两个方法可以独立变化而互不影响
利用闭包实现的单例
var getSingle = function(fn) {
var ret;
return function() {
return ret || (ret = fn.apply(this, arguments));
}
};
var getObject = getSingle(function() {
return new Object();
});
var obj1 = getObject();
var obj2 = getObject();
console.log(obj1 === obj2);
参考:《Javascript设计模式与开发实践》