定义
- 我自己的理解就是,一个类,只能实现一个实例,目的:是为了能够避免内存消耗问题,否则,你每次生成一个实例,都会重新开辟内存空间。
基本运用
function genGetInstance() {
let instance // 闭包
class Singleton {}
return () => {
if (instance == null) {
1instance = new Singleton
}
return instance
}
}
const getInstance = genGetInstance()
const s1 = getInstance()
const s2 = getInstance()
s1===s2
- 该单例,符合开放封闭原则,对外开放扩展,可以挂载方法和属性,但是对内是完全封闭的,内部的逻辑,外部是无法访问的。
- JS 是单线程语言, 如果是 Java 等多线程语言, 单例模式需要加线程锁
前端的应用
- vuex redux.
- 命名空间(nameSpace)确保全局对象命名唯一不冲突。
- 登录弹窗,被创建一次后被缓存,避免消耗内存。
Vuex
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)
}
-
这里补充一下,目前监控项目里面存在一个问题就是,每次初始化应用实例的时候,是可以被二次初始化的,的这里应该也可以去运用一下(抽空看能否落地);
这里如果不用单例会存在一个问题,就是当我二次注册store的时候,直接被初始化了会丢失原来的数据。
LocalStorage二次封装
- 因为localstorage作为存储用户信息,并且可以去做持久化登录的功能,所以可以去二次封装一下。
// 定义Storage
class Storage {
static getInstance() {
// 判断是否已经new过1个实例
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', 'scx');
storage1 === storage2