JavaScript设计模式-单例模式
概念
- 什么是单例模式:单例模式之所以这么叫,是因为它限制一个类只能有一个实例化对象。经典的实现方式是,创建一个类,这个类包含一个方法,这个方法在没有对象存在的情况下,将会创建一个新的实例对象。如果对象存在,这个方法只是返回这个对象的引用。
- 单例和静态类不同,因为我们可以退出单例的初始化时间。通常这样做是因为,在初始化的时候需要一些额外的信息,而这些信息在声明的时候无法得知。对于并不知晓对单例模式引用的代码来讲,单例模式没有为它们提供一种方式可以简单的获取单例模式。这是因为,单例模式既不返回对象也不返回类,它只返回一种结构。可以类比闭包中的变量不是闭包-提供闭包的函数域是闭包(绕进去了)。
例子
// 定义一个函数
const CreateDiv = (function () {
// 定义需要返回的实例对象
let instance
const CreateDiv = function (name) {
// 保证实例对象是唯一的,有就直接返回,没有就把this返回
if (instance) {
// instance.init(name)
return instance
}
this.init(name)
return instance = this
}
// 执行需要的方法函数
CreateDiv.prototype.init = function (name) {
this.name = name
}
return CreateDiv
})()
const a = new CreateDiv('sven1')
// console.log('a', a.name) // sven1
const b = new CreateDiv('sven2')
console.log(a === b) // true
console.log('a', a.name) // sven1
console.log('b', b.name) // sven1
单一职责原则
//这样我们确实用闭包来实现了一个单例,但这个代码还是高度耦合的,
// CreateDiv的构造函数实际上负责了两件事情。
// 第一是创建对象和执行初始化init方法,
// 第二是保证只有一个对象。
// 这样的代码是职责不明确的,现在我们要把这两个工作分开,
// 构造函数就负责构建对象,至于判断是返回现有对象还是构造新的对象并返回,我们交给另外一个函数去完成,
const CreateDiv = function (name) {
this.init(name)
}
CreateDiv.prototype.init = function (name) {
this.name = name
}
const ProxySingletonCreateDiv = (function () {
let instance
return function (name) {
if (!instance) {
instance = new CreateDiv(name)
}
// instance.init(name)
return instance
}
})()
const a = new ProxySingletonCreateDiv('sven1')
console.log('a', a.name)
const b = new ProxySingletonCreateDiv('sven2')
console.log(a === b) //true
console.log('a', a.name)
console.log('b', b.name)
惰性单例模式
const getSingleton = function (fn) {
let result
return function () {
return result || (result = fn.apply(this, arguments)) // 确定this上下文并传递参数
}
}
const createAlertMessage = function (html) {
console.log('我创建了')
const div = document.createElement('div')
div.innerHTML = html
div.style.display = 'none'
document.body.appendChild(div)
return div
}
const createSingleAlertMessage = getSingleton(createAlertMessage)
document.body.addEventListener('click', function () {
// 多次点击只会产生一个弹窗
const alertMessage = createSingleAlertMessage('不点击不出现!')
alertMessage.style.display = 'block'
})
总结
new 一个对象。有实例了就返回该实例,没有就创建一个新的返回。保证只有一个实例。
用处
常用-弹窗、页面登录框、防抖动 5.好处:对于频繁创建,销毁对象,这个单例模式实现了对象统一,内存只占有一个对象内存分量,在频繁创建中,大大的节约了系统内存。