分享一下今天在bilibili上学习了冰山工作室老师说的js单例模式,所以写了一个笔记,如果有什么不对的地方,还请多指教
什么是单例设计模式
单表示一个,例表示实例,所以单例设计模式指的就是只创建一个实例
其实说白了就是 无论你new多少次,都只创建一个实例对象
先来看一个简单的单例代码:
var instance;
function SingleInstance(content) {
this.init(content)
// 判断instance存不存在,如果存在则返回,如果不存在则把当前实例赋值给instance
return instance ? instance : (instance = this);
}
SingleInstance.prototype.init = function (content) {
this.content = content;
}
var foo = new SingleInstance('foo');
console.log(foo.content); // foo
var bar = new SingleInstance('bar');
console.log(bar.content); // foo
console.log(foo == bar); // true
其实上面的代码以及形成了一个单例,我们可以观察出foo==bar,说明无论你创建new多少次都只创建一个实例
下面对单例的代码进行改善
我们发现 foo.content 和bar.content都是foo
当第一次new的时候instance不存在,实例化了一次,当再次new的时候时直接return instance的
所以我们修改成instance调用
var instance;
function SingleInstance(content){
if(!instance){
instance = this;
}
instance.init(content);
return instance;
}
SingleInstance.prototype.init = function(content){
this.content = content;
}
继续优化:细心的同学肯定发现了instance定义在全局中,这样容易造成全局的污染
这里使用闭包使其改善成局部变量
我们将代码嵌套在匿名函数的自调用中
let SingleInstance = (function () {
var instance;
function SingleInstance(content) {
// 判断instance存不存在,如果存在则返回,如果不存在则把当前实例赋值给instance
if (!instance) {
instance = this;
}
instance.init(content);
return instance;
}
SingleInstance.prototype.init = function(content){
this.content = content;
}
return SingleInstance;
})();
继续优化
如果我们在外部不使用new的方式创建呢
var foo = SingleInstance('foo'); // 这里的this就不指向SingleInstance了,调用init就会报错
对this进行判断
let SingleInstance = (function () {
var instance;
function SingleInstance(content) {
instance = instance?instance:(this instanceof SingleInstance?this:new SingleInstance(content));
instance.init(content);
return instance;
}
SingleInstance.prototype.init = function (content) {
this.content = content;
}
return SingleInstance;
})();
var foo = SingleInstance('foo');
console.log(foo.content);
var bar = SingleInstance('bar');
console.log(bar.content);
console.log(foo==bar);// true
到此以及单例的最终版本了,使用了闭包,也实现了类名函数直接调用
总结:单例是我们面向对象编程设计的一种模式,始终遵循只创建一个对象的原则,单例一般用在网页中的单矿,因为弹框一般都只弹一次
网友评论