导言:如果你像我一样也是JavaScript的初学者并且希望更深一步理解Vue框架背后的设计思想的话,那么这篇文章或许会适合你。
单例模式
单例模式的定义是:
保证一个类仅有一个实例,并提供一个访问他的全局方法。
什么是单例模式呢,简单来说就是一个类只能创建一个实例,即使你创建了很多的实例,但如果通过===比较的话,你会发现,这些实例全部都是相等的。
那这有什么用呢?比如我们拿微信举例子,通常情况下无论是手机端还是PC端,你都只能登陆一个微信账号。而且你也只能打开一个微信登录界面,没有办法打开多个。这就是单例模式的一个应用场景,当我们会做一些限制操作的时候,会考虑使用单例模式。
JavaScript实现单例模式
在JavaScript中一个非常有用的单例模式实现方式称为惰性单例。我们希望单例模式是按需加载的,也就是需要单例模式的时候才生成单例模式对象,不需要的时候就不生成单例模式对象。代码实现如下:
class SingleObject {
login() {
console.log('login...')
}
}
// 定义一个静态方法
SingleObject.getInstance = (function () {
let instance
return function () {
if (!instance) {
instance = new SingleObject();
}
return instance
}
})()
// 测试:注意这里只能用静态函数getInstance, 不能new SingleObject()
let obj1 = SingleObject.getInstance()
obj1.login() // login...
let obj2 = SingleObject.getInstance()
obj2.login() // login...
console.log(obj1 === obj2) // true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
当我们以后调用的时候就会创建对应的单例模式对象。
我们根据单例模式这种设计思想,就可以实现微信登录只能同一时间保持打开一个登录页的功能。
const createLoginLayer = (function () {
let div
return function() {
if (!div) {
div = document.createElement('div')
div.innerHTML = '我是微信登录页面'
div.style.display = 'none'
document.body.appendChild(div)
}
return div
}
})()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
但我们上面的代码有一点小小的瑕疵。比如你有一个微信登录页功能想要使用单例模式,后面又来了一个登录后退出功能也想用单例模式,难道我们要把这样的代码结构再复制一遍吗?可能此时你会想,要是我们能把这内在的逻辑结构抽象成一个统一的组件,然后使用单例模式的时候调用这个组件就好了。下面我们来试试看:
const getSingle = function(fn) {
let result
return function() {
return result || (result = fn.apply(this, arguments))
}
}
- 1
- 2
- 3
- 4
- 5
- 6
我们创建一个getSingle函数,它的参数是一个函数,可以用来传入我们想要实现单例模式的功能函数。因为返回的是一个函数,里面有result参数,所以变量result不会因子调用getSingle结束之后被销毁。类似于之前单例模式的div
判别功能。
下面我们用定义的新方法实现微信登录页面的单例模式。
const createLoginLayer = function() {
const div = document.createElement('div')
div.innerHTML = '我是微信登录页面'
div.style.display = 'none'
document.body.appendChild(div)
return div
}
const createSingleLoginLayer = getSingle(createLoginLayer)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
Vuex中store
我们知道Vuex是用来做状态存储或者是数据存储的。我们想要不同页面访问获得的这个store值是完全一样的,这样才可以实现不同页面数据保持同步。所以store是通过单例模式实现的。
参考资料
[1] 《JavaScript设计模式与开发实践》