一个类只有一个实例,并提供一个访问它的全局访问点。

  1. class LoginForm {
  2. constructor() {
  3. this.state = 'hide'
  4. }
  5. show() {
  6. if (this.state === 'show') {
  7. alert('已经显示')
  8. return
  9. }
  10. this.state = 'show'
  11. console.log('登录框显示成功')
  12. }
  13. hide() {
  14. if (this.state === 'hide') {
  15. alert('已经隐藏')
  16. return
  17. }
  18. this.state = 'hide'
  19. console.log('登录框隐藏成功')
  20. }
  21. }
  22. LoginForm.getInstance = (function () {
  23. let instance
  24. return function () {
  25. if (!instance) {
  26. instance = new LoginForm()
  27. }
  28. return instance
  29. }
  30. })()
  31. let obj1 = LoginForm.getInstance()
  32. obj1.show()
  33. let obj2 = LoginForm.getInstance()
  34. obj2.hide()
  35. console.log(obj1 === obj2)

优点

  • 划分命名空间,减少全局变量
  • 增强模块性,把自己的代码组织在一个全局变量名下,放在单一位置,便于维护
  • 且只会实例化一次。简化了代码的调试和维护

    缺点

  • 由于单例模式提供的是一种单点访问,所以它有可能导致模块间的强耦合 从而不利于单元测试。无法单独测试一个调用了来自单例的方法的类,而只能把它与那个单例作为一个单元一起测试。

    场景例子

  • 定义命名空间和实现分支型方法

  • 登录框
  • vuex 和 redux中的store