单例模式是比较常见的一种设计模式,基于此可以延伸出一个惰性单例的使用方法,以登录框为例
// version 1 缺点是初始化时就会执行登录框的实例化,但是有时候这个动作不一定会触发
const loginDialog = (function(){
const dialog = document.createElement('div')
dialog.innerHTML = '登录'
// 设置样式
dialog.style.display = 'none'
dialog.style.xxxx = xxx
document.appendChild(dialog)
return dialog
})()
document.getElementById('btn').onclick=() => {
loginDialog.style.display = 'block'
console.log('请登录')
}
// version 2 虽然初始化时不会触发实例化,但是每次展现弹窗都会实例化一次
const getLoginDialog = function(){
const dialog = document.createElement('div')
dialog.innerHTML = '登录'
// 设置样式
dialog.style.display = 'none'
dialog.style.xxxx = xxx
document.appendChild(dialog)
return dialog
}
document.getElementById('btn').onclick=() => {
const loginDialog = getLoginDialog()
loginDialog.style.display = 'block'
console.log('请登录')
}
// version 3 将实例化的操作和单例的使用结合起来。只在用到的时候才实例化,并且多次创建也只实例化一次
const getSingle = function(fn){
let single = null
return function(){
if (!single) {
single = fn.apply(this,arguments)
}
return single
}
}
const createLoginDialog = function(){
const dialog = document.createElement('div')
dialog.innerHTML = '登录'
// 设置样式
dialog.style.display = 'none'
dialog.style.xxxx = xxx
document.appendChild(dialog)
return dialog
}
const getLoginDialog = getSingle(createLoginDialog)
document.getElementById('btn').onclick=() => {
const loginDialog = getLoginDialog()
loginDialog.style.display = 'block'
console.log('请登录')
}
第三个版本明显要优于前两个版本,并且拆分了判断是否单例和具体实例化的逻辑,这是符合单一职责原则的。这样在实现惰性单例的基础上,还可以提升复用度