js设计模式——单例模式

定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

Vue 中对应的体现就是 Vuex,一个 Vue 实例只会有一个全局的 Store。

一、JavaScript 中的单例模式

在 JavaScript 开发中,我们经常会把全局变量当成单例来使用,但是这样容易造成命名空间污染。我们有必要尽量减少全局变量的使用,即使需要,也应该把污染降到最低。

1. 使用命名空间

适当的使用命名空间,并不会杜绝全局变量,但可以减少全局变量的数量。

let MyApp = {};

MyApp.namespace = (name) => {
  const parts = name.split('.')
  let current = MyApp
  for (var i in parts) {
    const key = parts[i]
    if ( !current[key] ) {
      current[key] = {}
    }
    current = current[key]
  }
};

MyApp.namespace('event')
MyApp.namespace('dom.stype')

console.dir(MyApp)

// 上述代码等价于

let MyApp = {
  event: {},
  dom: {
    style: {}
  }
};
2. 使用闭包封装私有变量

把一些变量封装到闭包内部,只暴露一些接口跟外界通信:

const user = (() => {
  const _name = 'sven', _age = 29
  return {
    getUserInfo: () => {
      return _name + '-' + _age
    }
  }
})();

console.log(user.getUserInfo())

二、惰性单例

惰性单例指的是在需要的时候才创建对象实例。

// 管理单例
const getSingle = function(fn) {
  let result
  return () => {
    return result || ( result = fn.apply(this, arguments) )
  }
}

const createLoginLayer = () => {
  const div = document.createElement('div')
  div.innerHTML = '我是登录浮窗'
  document.body.appendChild(div)
  return div
}

const createSingleLoginLayer = getSingle(createLoginLayer)
var loginLayer = createSingleLoginLayer()
var loginLayer = createSingleLoginLayer()
var loginLayer = createSingleLoginLayer()


const createSingleIframe = getSingle(() => {
  const iframe = document.createElement('iframe')
  document.body.appendChild(iframe)
  return iframe
})
var iframe = createSingleIframe()
var iframe = createSingleIframe()
var iframe = createSingleIframe()

三、例子

  • 描述(实现一个 Storage)
    实现 Storage,使得该对象为单例,基于 localStorage 进行封装。实现方法 setItem(key,value) 和 getItem(key)。

  • 实现 1 (闭包实现 Storage)

function StoreBase(){}
StoreBase.prototype.getItem = (key) => {
  return localStorage.getItem(key)
}
StoreBase.prototype.setItem = (key, val) => {
  localStorage.setItem(key, val)
}

const Store = (() => {
  let instance = null
  return () => {
    if (!instance) {
      instance = new StoreBase()
    }
    return instance
  }
})()

const store1 = Store()
const store2 = Store()

store1.setItem('name', '张三')

store2.getItem('name') // 张三
store1.getItem('name') // 张三

console.log(store1 === store2) //
  • 实现 2 (静态类实现 Storage)
class Storage {
  static getInstance() {
    if (!Storage.instance) {
      Storage.instance = new Storage()
    }
    return Storage.instance
  }
  getItem(key) {
    return localStorage.getItem(key)
  }
  setItem(key, value) {
    localStorage.setItem(key, value)
  }
}

const storage1 = Storage.getInstance()
const storage2 = Storage.getInstance()

storage1.setItem('name', '张三')
storage1.getItem('name')
storage2.getItem('name')

console.log(storage1 === storage2)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该文档是根据博客园汤姆大叔的深入理解JavaScript系列(http://www.cnblogs.com/TomXu/archive/2011/12/15/2288411.html)博文整理而成,主要内容包括: 1.编写高质量JavaScript代码的基本要点 2.揭秘命名函数表达式 3.全面解析Module模式 4.立即调用的函数表达式 5.强大的原型和原型链 6.S.O.L.I.D五大原则之单一职责SRP 7.S.O.L.I.D五大原则之开闭原则OCP 8.S.O.L.I.D五大原则之里氏替换原则LSP 9.根本没有“JSON对象”这回事! 10.JavaScript核心(晋级高手必读篇) 11.执行上下文(Execution Contexts) 12.变量对象(Variable Object) 13.This? Yes,this! 14.作用域链(Scope Chain) 15.函数(Functions) 16.闭包(Closures) 17.面向对象编程之一般理论 18.面向对象编程之ECMAScript实现 19.求值策略 20.《你真懂JavaScript吗?》答案详解 21.S.O.L.I.D五大原则之接口隔离原则ISP 22.S.O.L.I.D五大原则之依赖倒置原则DIP 23.JavaScript与DOM(上)——也适用于新手 24.JavaScript与DOM(下) 25.设计模式单例模式 26.设计模式之构造函数模式 27.设计模式之建造者模式 28.设计模式之工厂模式 29.设计模式之装饰者模式 30.设计模式之外观模式 31.设计模式之代理模式 32.设计模式之观察者模式 33.设计模式之策略模式 34.设计模式之命令模式 35.设计模式之迭代器模式 36.设计模式之中介者模式 37.设计模式之享元模式 38.设计模式之职责链模式 39.设计模式之适配器模式 40.设计模式之组合模式 41.设计模式之模板方法 42.设计模式之原型模式 43.设计模式之状态模式 44.设计模式之桥接模式 45.代码复用模式(避免篇) 46.代码复用模式(推荐篇) 47.对象创建模式(上篇) 48.对象创建模式(下篇)
深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点 深入理解JavaScript系列(2):揭秘命名函数表达式 深入理解JavaScript系列(3):全面解析Module模式 深入理解JavaScript系列(4):立即调用的函数表达式 深入理解JavaScript系列(5):强大的原型和原型链 深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP 深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP 深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP 深入理解JavaScript系列(9):根本没有“JSON对象”这回事! 深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇) 深入理解JavaScript系列(11):执行上下文(Execution Contexts) 深入理解JavaScript系列(12):变量对象(Variable Object) 深入理解JavaScript系列(13):This? Yes, this! 深入理解JavaScript系列(14):作用域链(Scope Chain) 深入理解JavaScript系列(15):函数(Functions) 深入理解JavaScript系列(16):闭包(Closures) 深入理解JavaScript系列(17):面向对象编程之一般理论 深入理解JavaScript系列(18):面向对象编程之ECMAScript实现 深入理解JavaScript系列(19):求值策略 深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解 深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP 深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP 深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手 深入理解JavaScript系列(24):JavaScript与DOM(下) 深入理解JavaScript系列(25):设计模式单例模式 深入理解JavaScript系列(26):设计模式之构造函数模式 深入理解JavaScript系列(27):设计模式之建造者模式 深入理解JavaScript系列(28):设计模式之工厂模式 深入理解JavaScript系列(29):设计模式之装饰者模式 深入理解JavaScript系列(30):设计模式之外观模式 深入理解JavaScript系列(31):设计模式之代理模式 深入理解JavaScript系列(32):设计模式之观察者模式 深入理解JavaScript系列(33):设计模式之策略模式 深入理解JavaScript系列(34):设计模式之命令模式 深入理解JavaScript系列(35):设计模式之迭代器模式 深入理解JavaScript系列(36):设计模式之中介者模式 深入理解JavaScript系列(37):设计模式之享元模式 深入理解JavaScript系列(38):设计模式之职责链模式 深入理解JavaScript系列(39):设计模式之适配器模式 深入理解JavaScript系列(40):设计模式之组合模式 深入理解JavaScript系列(41):设计模式之模板方法 深入理解JavaScript系列(42):设计模式之原型模式 深入理解JavaScript系列(43):设计模式之状态模式 深入理解JavaScript系列(44):设计模式之桥接模式 深入理解JavaScript系列(45):代码复用模式(避免篇) 深入理解JavaScript系列(46):代码复用模式(推荐篇) 深入理解JavaScript系列(47):对象创建模式(上篇) 深入理解JavaScript系列(48):对象创建模式(下篇) 深入理解JavaScript系列(49):Function模式(上篇) 深入理解JavaScript系列(50):Function模式(下篇) 深入理解JavaScript系列(结局篇)

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值