单例模式
单例模式是保证一个类只有一个实例,并且提供一个访问它的全局访问点。实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。 主要是为了解决一个全局使用的类频繁地创建和销毁,占用内存
几种实现方式
列几种简单实现方式
1.通过面向对象实现
// 单例设计模式的实现:面向对象
let Singleton = function(name) {
this.name = name;
this.instance = null;
}
Singleton.prototype.getName = function(){
return this.name;
}
Singleton.getInstance = function(name) {
if(!this.instance) {
this.instance = new Singleton(name);
}
return this.instance;
}
let instance1 = Singleton.getInstance('张三');
let instance2 = Singleton.getInstance('李四');
console.log(instance1===instance2); // 输出true
2.通过立即执行函数+闭包 实现
利用立即执行函数只执行一次的特点
var Singleton = (function(){
var instance
function User(name, age) {
this.name = name
this.age = age
}
return function(name,age){
if(!instance) {
instance = new User(name,age)
}
return instance
}
}
)()
Singleton() === Singleton() // true
3.通过es6 class实现
class Singleton{
constructor(name,age) {
if(!Singleton.instance) {
this.name = name
this.age = age
Singleton.instance = this
}
return Singleton.instance
}
}
new Singleton('zs',18) === new Singleton('ls',22)
应用场景
全局都只用一个实例对象,如:全局弹窗、状态管理redux/vuex、全局缓存、浏览器中的window对象...
vuex中单例:
// src/store.js
let Vue;
export class Store {
constructor(options = {}) {
if (!Vue && typeof window !== 'undefined' && window.Vue) {
install(window.Vue)
}
}
}
export function install (_Vue) {
if (Vue && _Vue === Vue) {
if (__DEV__) {
console.error(
'[vuex] already installed. Vue.use(Vuex) should be called only once.'
)
}
return
}
Vue = _Vue
applyMixin(Vue)
}
单例模式的优缺点
优点
- 提供了对唯一实例的受控访问
- 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。比起实例不断地销毁和重新实例化,单例能节约更多资源
- 避免对资源的多重占用
- 减小垃圾回收机制 GC的压力,表现在浏览器中就是系统卡顿减少,操作更流畅;
缺点
- 由于单例模式,不是抽象的所以可扩展性比较差。
- 单例类,职责过重,在一定程度上违背了单一职责。