内容速递:看了本文您能了解到的知识

一句话介绍:保证类的实例只有一个。
说到类,JS在ES6提供了更接近面向对象语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。
注意:JavaScript本质上是基于对象的语言
其实,ES6的Class可以看作只是Function的语法糖,它的绝大部分功能,ES5的Function都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
单例模式在前端应用范围内有很多应用场景。
很典型的单例模式的应用。Vuex的store就是一个单例模式。采用了单一状态树,一个对象即为唯一数据源。
可以简单看一下Vuex源码
let Vue
...
export function install (_Vue) {
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 = _Vue
applyMixin(Vue)
}
可以看到Vuex在install的时候,判断是否有了唯一的state。反之,如果没有这一段逻辑,在Vue中使用的时候
// 安装插件
Vue.use(Vuex)
...(Vuex操作)
// 再次安装
Vue.use(Vuex)
再次安装的时候,唯一数据源store被重新生成,中间的Vuex操作就没有了
Redux提供的全局的store,和Vuex一样,必须是一个单例模式,不然每个组件各玩各的,如何实现数据协调同步呢。
在前端中有一些全局组件,例如:创建全局唯一的对话框实例、记录日志信息全局唯一实例、登录弹窗、购物车等等。
这些组件都有一个特点,只有一个实例,状态唯一。
在ES6中,import 引入的模块是会自动执行的,但是有的时候我们可能会重复引入一个模块,但是这个时候不会执行多次,因为import就用到了SIngleton模式。
还想看吗?可重点不是列举额,那这里也不多列举了,只能给你展示更多了!
思路很简单,那就是一个类只有一个实例。
那怎么做到一个类只有一个实例?
去获取一个类的实例之前,去判断一下这个实例是否存在,如果存在直接把这个实例返回,那这样,不就是一个类只有一个实例了吗?
一个正常的类
每次new出来的实例都是不一样的
class SingleItem {
show() {
console.log('我是一个单例')
}
}
const s1 = new SingleItem()
const s2 = new SingleItem()
console.log(s1 === s2)
// false
借助Class和static实现单例
class SingleItem {
static instance
show() {
console.log('我是一个单例')
}
static getInstance() {
return SingleItem.instance || (SingleItem.instance = new SingleItem())
}
}
const s1 = SingleItem.getInstance()
const s2 = SingleItem.getInstance()
console.log(s1 === s2)
// true
单一职责原则。听说是一个面试题!
问题描述:
实现一个Storage,让该对象成为单例对象,可以基于localStorage实现。
思路:
1、获取实例
2、实例唯一
代码:
class Storage {
static instance
static getInstance() {
return Storage.instance || (Storage.instance = new Storage())
}
getItem(key) {
return localStorage.getItem(key)
}
setItem(key, value) {
localStorage.setItem(key, value)
}
}
测试一下:
const s1 = Storage.getInstance()
const s2 = Storage.getInstance()
s1.setItem('name', 'aaa')
// 测试两个的实例是否为同一个
s1.getItem('name') // aaa
console.log(s1.getItem('name'))
s2.getItem('name') // aaa
console.log(s2.getItem('name'))
console.log(s1 === s2)
// true
面试题+1
问题描述:
用单例模式写一个全局的Modal框
思路:
1、获取实例
2、实例唯一
这里也可以通过闭包来实现
代码:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>单例Modal框title>
head>
<body>
<div id="openModal">打开Modal框div>
<div id="closeModal">关闭Modal框div>
body>
<script>
// 实现Modal框
const Modal = (function() {
let modal = null
return function() {
if (!modal) {
modal = document.createElement('div')
modal.innerHTML = '我是Modal框'
modal.style.display = 'none'
document.body.appendChild(modal)
}
return modal
}
})()
document.getElementById('openModal').addEventListener('click', function() {
const modal = new Modal()
modal.style.display = 'block'
})
document.getElementById('closeModal').addEventListener('click', function() {
const modal = new Modal()
modal && (modal.style.display = 'none')
})
script>
html>
慢慢开发的年龄大了,就越想搞点新玩意,但是编程的思维却越来越需要有足够的长进。最近要做一个JS-SDK,单例的思想值得好好琢磨琢磨!
文章所涉及的部分资料来自互联网整理,其中包含自己个人的总结和看法,分享的目的在于共建社区和巩固自己。
引用的资料如有侵权,请联系本人删除!
感谢万能的网络,W3C,菜鸟教程等!
如果你感觉对你有帮助的话,不妨给我点赞鼓励一下,好文记得收藏哟!关注我一起成长!
幸好我在,感谢你来!