单例模型
单例模式(Singleton Pattern)是一种创建型设计模式,它确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。在JavaScript中,单例模式常用于管理全局状态、配置信息或实现全局缓存等场景。
单例模型的使用场景
当你创建一个比较大的对象,比如使用一个AI的大模型。为了节省空间,只在第一次使用该AI大模型的时候创建一个实例对象,在后续的使用中不再创建新的实例对象,只使用同一个对象。
单例对象模型的写法
ES6写法
在ES6中,可以使用类语法和静态方法来创建单例。
class SingleDog {
show() {
console.log('我是一个单身狗')
}
static getInstance() {
if (!SingleDog.instance) (
SingleDog.instance = new SingleDog()
)
return SingleDog.instance;
}
}
const s1 = SingleDog.getInstance();
const s2 = SingleDog.getInstance();
console.log(s1 === s2)
闭包写法
通过闭包可以创建一个私有的命名空间,确保单例的唯一性
class SingleDog {
show() {
console.log('我是一个单身狗')
}
}
SingleDog.getInstance = (function () {
let instance = null;
return function () {
if (!instance) {
instance = new SingleDog()
}
return instance
}
})()
const s1 = SingleDog.getInstance();
const s2 = SingleDog.getInstance();
console.log(s1 === s2)
这里利用了瞬时函数,调用完成后返回一个函数,产生闭包
实战案例
设计两个按钮,一个打开全局弹窗,一个关闭全局弹窗。
这里写了一份代码,没使用单例模式,对一个窗口进行操作,只会产生新的弹窗。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#model {//设计弹窗的样式
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #000;
}
</style>
</head>
<body>
<button id="open">打开弹框</button>
<button id="close">关闭弹框</button>
<script>
const model = function (flag) {//写一个能生成一个对象的函数
let div = document.createElement('div')
div.innerHTML = '我是一个全局弹框'
div.id = 'model'
div.style.display = flag
document.body.appendChild(div)
}
document.getElementById('open').addEventListener('click', () => {
model('block')//此处点击会产生一个新的model,属性为block,会显现出来
})
document.getElementById('close').addEventListener('click', () => {
model('none')//此处点击会产生一个新的model,属性为none,不会显现出来
})
</script>
</body>
</html>
此处利用闭包创建单例模型的方法,只会创建一个弹窗model的对象,只修改弹窗的display的展示形式,来实现开关弹窗的功能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#model {
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid #000;
}
</style>
</head>
<body>
<button id="open">打开弹框</button>
<button id="close">关闭弹框</button>
<script>
const Model = (function () {
let model = null
return function (flag) {
if (!model) {
model = document.createElement('div')
model.innerHTML = '我是一个弹框'
model.id = 'model'
document.body.appendChild(model)
}
model.style.display = flag
return moddle
}
})()
document.getElementById('open').addEventListener('click', () => {
Model('block')
})
document.getElementById('close').addEventListener('click', () => {
Model('none')
})
</script>
</body>
</html>