**定义:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。
单例模式是一个比较常用的设计模式,有些对象往往我们只需要一个,使用场景例如有购物车、全局缓存等
举个例子:我们将使用 CreateDiv 单例类,它的作用是负责在页 面中创建唯一的 div 节点用代码实现下这个简单的例子
var CreateDiv = (function(){
var instance // 是否创建过实例的标志
var CreateDiv = function( html ){
if ( instance ){ // 若已创建过实例则在下一次获取该类的实例时,直接返回之前创建的对象
return instance
}
this.html = html
this.init()
return instance = this // 首次创建实例,将实例保存
}
// 渲染创建的div
CreateDiv.prototype.init = function(){
var div = document.createElement( 'div' )
div.innerHTML = this.html
document.body.appendChild( div )
}
return CreateDiv
})()
var a = new CreateDiv( 'ele1' )
var b = new CreateDiv( 'ele2' )
alert ( a === b ) // true
看到这里,可能有个疑问,既然我们只需要一个“唯一”的对象,为什么要为它先创建一个“类”呢?因为在javasript中,创建一个全局对象十分简单,只需要var obj = {}就可以了,那为什么要使用单例模式呢,首先,全局变量不是单例模式,声明obj这个的确是个全局对象,但是他并不是存在“唯一”的,因为随着项目的扩大,如果存在很多这种全局变量,它就很容易造成命名空间的污染,后续维护起来就会很痛苦。虽然现在已经完成了一个单例模式的编写,但这段单例模式代码的意义并不大。
场景:一个网购平台的web项目,我们选购商品并加入购物车,当我们选择好商品并点击购物车图标才打开购物车弹窗。
一般的思路就是先在加载的时候就把购物车弹窗创建好,然后隐藏它,点击图标时再显示;但是如果我们只是浏览商品,而没有打算购买的时候,加载这个弹窗显得有点浪费。所有这里就能用到惰性的单例模式。
var createLoginLayer = (function(){
var div
return function(){
if ( !div ){
div = document.createElement( 'div' )
div.innerHTML = '购物车弹窗'
div.style.display = 'none'
document.body.appendChild( div )
}
return div
}
})()
document.getElementById( 'loginBtn' ).onclick = function(){
var loginLayer = createLoginLayer()
loginLayer.style.display = 'block'
}
**小结:**单例模式是一种简单但非常实 用的模式,特别是惰性单例技术,在合适的时候才创建对象,并且只创建唯一的一个。惰性单例技术可以很好的避免对象丢失或者覆盖,延迟的创建对象能很好的避免资源的浪费。