js单例模式

77 阅读2分钟

单例模式

单例模式是保证一个类只有一个实例,并且提供一个访问它的全局访问点。实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。 主要是为了解决一个全局使用的类频繁地创建和销毁,占用内存

几种实现方式

列几种简单实现方式

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的压力,表现在浏览器中就是系统卡顿减少,操作更流畅;

缺点

  • 由于单例模式,不是抽象的所以可扩展性比较差。
  • 单例类,职责过重,在一定程度上违背了单一职责。