JS设计模式-单例模式
单例模式:限制类只能有一个实例化对象。模式特点:类只有一个实例全局可访问推迟初始化(与静态类,对象的区别)主动实例化实现方法:创建一个类,这个类包含一个方法。在没有对象的情况下,这个方法会创建一个新的实例对象。如果对象存在,则只返回对象的引用地址。应用场景:登录弹窗购物车命名空间引入第三方库(多次引用只会使用一个库引用,如jQuery)全局态管理store-Vuex优缺点:优点:适用于单一对象,只
·
单例模式:限制类只能有一个实例化对象。
模式特点:
- 类只有一个实例
- 全局可访问
- 推迟初始化(与静态类,对象的区别)
- 主动实例化
实现方法:
创建一个类,这个类包含一个方法。在没有对象的情况下,这个方法会创建一个新的实例对象。如果对象存在,则只返回对象的引用地址。
应用场景:
- 登录弹窗
- 购物车
- 命名空间
- 引入第三方库(多次引用只会使用一个库引用,如jQuery)
- 全局态管理store-Vuex
优缺点:
- 优点:适用于单一对象,只生成一个对象实例,避免频繁创建和销毁实例,减少内存占用
- 缺点:不适用动态扩展对象,或需创建多个相似对象的场景
“简单版”单例模式:
let Signleton = function(name){
this.name = name
this.instance = null
}
Signleton.prototype.getName = function(){
console.log(this.name);
}
Signleton.getInstance = function(name){
if(this.instance){
return this.instance
}
return this.instance = new Signleton(name)
}
let Winner = Signleton.getInstance('Winner')
let Loser = Signleton.getInstance('Loser')
console.log(Winner === Loser);
console.log(Winner.getName()); // Winner
console.log(Loser.getName()); //Loser
"透明版"单例模式
统一使用 new
在进行实例化,创建实例功能和管理实例功能分离,使其符合‘单一职责原则’
let createSignleton = (function(){
let instance;
return function(name){
if(instance){
return instance
}
this.name = name
return instance = this
}
})()
createSignleton.prototype.getName = function(){
console.log(this.name);
}
let Winner = new createSignleton('Winner')
let Loser = new createSignleton('Loser')
console.log(Winner === Loser);
console.log(Winner.getName()); // Winner
console.log(Loser.getName()); //Loser
“代理版”单例模式
通过代理的模式,意图将创建单例,管理单例拆分,实现更小的粒度划分,符合‘单一职责原则’
let ProxyCreateSignleton = (function(){
let instance;
return function(name){
// 代理函数只做管理单例
if(instance){
return instance
}
return instance = new Signleton(name)
}
})()
// 独立的Signleton类,处理对象实例
let Signleton = function(name){
this.name = name
}
Signleton.prototype.getName = function(){
console.log(this.name);
}
let Winner = new ProxyCreateSignleton('Winner')
let Loser = new ProxyCreateSignleton('Loser')
console.log(Winner === Loser);
console.log(Winner.getName()); // Winner
console.log(Loser.getName()); //Loser
“惰性”单例模式
需要时才创建实例对象,按需加载。
需求:页面弹窗提示。多次调用,都只有一个弹窗对象,内部html不同
let getSignleton = function(fn){
var result;
return function(){
return result || (result = fn.apply(this, arguments))
}
}
let createAlterMessage = function(html){
var div = document.createElement('div')
div.innerHTML = html;
div.style.display = 'none'
document.body.appendChild(div)
return div
}
let createSignletonAlterMessage = getSignleton(createAlterMessage)
document.getElementById('btn').addEventListener('click', function(){
let alterMessage = createAlterMessage('这是唯一弹窗')
alterMessage.style.display = 'block'
})
参考文章:
https://segmentfault.com/a/1190000019532633
https://www.jianshu.com/p/7fa6ea107eff
https://juejin.cn/post/6909737165157203982#comment
更多推荐
已为社区贡献1条内容
所有评论(0)