JavaScript设计模式学习笔记(五)——单例模式

175 阅读2分钟

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

单例模式是一个比较常用的设计模式,有些对象往往我们只需要一个,使用场景例如有购物车、全局缓存等

举个例子:我们将使用 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' 
}

**小结:**单例模式是一种简单但非常实 用的模式,特别是惰性单例技术,在合适的时候才创建对象,并且只创建唯一的一个。惰性单例技术可以很好的避免对象丢失或者覆盖,延迟的创建对象能很好的避免资源的浪费。