Skip to content
On this page

单例模式

保证一个类仅有一个实例,并提供一个访问它的全局访问点,这个就是单例。

实现思路

创建一个类,并实例化它

javascript
class User {
  speak() {
    console.log('我是一个实例对象')
  }
}

const u1 = new User()
const u2 = new User()

console.log(u1 === u2) // false

先 new 了一个 s1,又 new 了一个 s2,很明显 s1 和 s2 之间没有任何瓜葛,两者是相互独立的对象,各占一块内存空间。而单例模式想要做到的是,不管我们尝试去创建多少次,它都只给你返回第一次所创建的那唯一的一个实例

要做到这一点,就需要构造函数具备判断自己是否已经创建过一个实例的能力。

javascript
class User {
  speak() {
    console.log('我是一个实例对象')
  }

  static getInstance() {
    if (!User.instance) {
      User.instance = new User()
    }
    return User.instance
  }
}

const u1 = User.getInstance()
const u2 = User.getInstance()

console.log(u1 === u2) // true

实现示例

javascript
class Storege {

  static getInstance() {
    if (!Storege.instance) {
      Storege.instance = new Storege()
    }
    return Storege.instance;
  }

  set(key, value) {
    localStorage.setItem(key, value);
  }

  remove(key) {
    localStorage.removeItem(key);
  }
}

const a = Storege.getInstance();

a.set('__val', 1);


function StoregeBase() {}

StoregeBase.prototype.set = function(key, val) {
  localStorage.setItem(key, val)
}

StoregeBase.prototype.get = function(key) {
  return localStorage.getItem(key)
}

const StoregeB = (function() {
  let instance = null;
  return function() {
    if (!instance) {
      instance = new StoregeBase()
    }

    return instance;
  }
})()

var b = new StoregeB()

b.set('aa', 111);


// modal
class Modal {
  constructor(options) {
    this.options = options
    return Modal.getInstance.call(this);
  }

  static getInstance() {
    if (!Modal.instance) {
      Modal.instance = document.createElement('div')
      Modal.instance.innerHTML = this.options.text;
      Modal.instance.id = 'modal'
      Modal.instance.style.display = 'block'
      var btn = document.createElement('button');
      btn.innerText = '确认'
      btn.onclick = this.options.confirm ? this.options.confirm.bind(this, this.close) : this.close;
      Modal.instance.appendChild(btn)
      document.body.appendChild(Modal.instance)
    }

    return Modal.instance
  }

  close() {
    Modal.instance = null;
    document.body.remove(Modal.instance)
    // if (this.options.confirm) {
    //   this.options.confirm()
    // }
  }
}