共计 2861 个字符,预计需要花费 8 分钟才能阅读完成。
单例模式
保障一个类仅有一个实例,并提供一个拜访它的全局拜访点。
个别能够用一个变量去标记,是否曾经为某个类创立过实例,如果是,则返回该实例,如果不是,则创立新的实例。
Vuex 中的单例模式
其实不论是 Vuex 还是 Redux,它们都采纳了单例模式。两者都用一个全局的惟一 Store 来存储所有状态。
在 Vue 我的项目中,咱们通过 Vue.use(Vuex)
来装置 Vuex 插件,该插件是一个对象模式,外部实现一个 install 办法。在装置插件时,会调用该办法,而后把 store 注入 Vue 实例中。
在 install 办法中采纳单例模式,管制 store 全局惟一。
let Vue // 利用闭包保留变量不被销毁
...
export function install (_Vue) {
// 判断传入的 Vue 实例对象是否曾经被 install 过 Vuex 插件(是否有了惟一的 state)if (Vue && _Vue === Vue) {if (process.env.NODE_ENV !== 'production') {
console.error('[vuex] already installed. Vue.use(Vuex) should be called only once.'
)
}
return
}
// 若没有,则为这个 Vue 实例对象 install 一个惟一的 Vuex
Vue = _Vue
// 将 Vuex 的初始化逻辑写进 Vue 的钩子函数里
applyMixin(Vue)
}
- 通过闭包保留标记量,不被销毁
- 判断 vue 实例是否曾经注入过 store,如果是间接返回
- 若没有,则为这个实例对象创立一个惟一的 Vuex,将 Vuex 的初始化逻辑写进 Vue 的钩子函数里。
思考:如果 install 函数中不采纳单例模式会产生什么?
若不应用单例模式,并且屡次调用 Vue.use(Vuex)
,那么会给 Vue 实例注入新的 store, 之前的数据都会清空。
单例模式的利用
实现一个 Storage
形容:实现 Storage,使得该对象为单例,基于 localStorage 进行封装。实现办法 setItem(key,value) 和 getItem(key)。
办法一:静态方法版
// 静态方法版
class Storage {static getInstance() {
// 判断是否曾经有实例
if (!Storage.instance) {
// 没有则创立
Storage.instance = new Storage();}
// 有则返回
return Storage.instance;
}
getItem(key) {return localStorage.getItem(key);
}
setItem(key, value) {return localStorage.setItem(key, value);
}
}
const storage1 = Storage.getInstance();
const storage2 = Storage.getInstance();
storage1.setItem('name', 'pengpeng');
storage2.setItem('name', 'linlin');
console.log(storage1.getItem('name')); // linlin
console.log(storage1 === storage2); // true
办法二:闭包版
// 闭包版
// 1、根底的 StorageBase 类,把 getItem 和 setItem 办法放在它的原型链上
function StorageBase() {};
StorageBase.prototype.getItem = function (key) {return localStorage.getItem(key);
};
StorageBase.prototype.setItem = function (key, value) {return localStorage.setItem(key, value);
}
// 2、创立构造函数, 利用闭包以及立刻执行函数
const Storage = (function () {
let instanse = null;
return function () {if (!instanse) {instanse = new StorageBase();
}
return instanse;
}
})();
const storage3 = new Storage();
const storage4 = new Storage();
storage3.setItem('age', 18);
storage4.setItem('age', 22);
console.log(storage3.getItem('age')); // 22
console.log(storage3 === storage4); // true
实现一个全局的模态框
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> 单例模式弹框 </title>
</head>
<style>
#modal {
height: 200px;
width: 200px;
line-height: 200px;
position: fixed;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border: 1px solid black;
text-align: center;
}
</style>
<body>
<button id='open'> 关上弹框 </button>
<button id='close'> 敞开弹框 </button>
</body>
<script>
// 外围逻辑,这里采纳了闭包思路来实现单例模式
const Modal = (function () {
let modal = null
return function () {if (!modal) {modal = document.createElement('div')
modal.innerHTML = '我是一个全局惟一的 Modal'
modal.id = 'modal'
modal.style.display = 'none'
document.body.appendChild(modal)
}
return modal
}
})()
// 点击关上按钮展现模态框
document.getElementById('open').addEventListener('click', function () {
// 未点击则不创立 modal 实例,防止不必要的内存占用; 此处不必 new Modal 的模式调用也能够,和 Storage 同理
const modal = new Modal()
modal.style.display = 'block'
})
// 点击敞开按钮暗藏模态框
document.getElementById('close').addEventListener('click', function () {const modal = new Modal()
if (modal) {modal.style.display = 'none'}
})
</script>
</html>
正文完
发表至: javascript
2022-05-17