JavaScript設計模式學習—單例模式

什麼是單例模式

簡單點來講,單例模式就是確保某個類只有一個實例,而且最好只被建立過一次。對計算機來講,像打印機,線程池都是經典的單例模式。對於JavaScript所處的前端環境來講,像登陸懸浮框,在整個頁面中只會有一個,不管用戶點擊多少次,只會被建立一次。前端

單例模式實現實例—登陸框

單例模式很是好理解,無非是辦公室有個打印機,你們一塊兒公用,不必再每一個人單獨買一個了。因此按照這樣的理解,先寫出前端建立懸浮登陸框的前端代碼:設計模式

var createLoginDialog = function(){
    var div = document.createElement('div');
    div.innerHTML='登陸懸浮框';
    var closeBtn = document.createElement('button');
    closeBtn.innerHTML = 'X';
    div.appendChild(closeBtn);
    closeBtn.onclick = function(){
        div.style.display='none';
    }
    document.body.appendChild(div);
    return div;
}
document.getElementById('loginBtn').onclick = function(){
    var loginDiv = createLoginDialog();
}

這應該是咱們平時寫出的「通常」實現單例代碼,看起來單例是實現了。但有很大問題,就是每次建立都會新生成一個div,性能損耗不談,自己也不是真正實現了單例模式。
單例模式的關鍵實現一是要在須要建立的時候纔開始建立,即惰性建立,第二就是隻被建立一次,再次使用的時候,不須要重複建立。在其餘語言實現中,須要藉助靜態方法或者其餘手段來使代碼駐留內存,達到這一目的。JavaScript卻不提供,但內存駐留卻使咱們想到了閉包。
因此再次修改代碼,建立一個閉包來實現。閉包

var createLoginDialog = (function(){
        var div;
        return function(){
            if(!div){
                    div = document.createElement('div');
                    div.innerHTML='登陸懸浮框';
                    var closeBtn = document.createElement('button');
                    closeBtn.innerHTML = 'X';
                    div.appendChild(closeBtn);
                    closeBtn.onclick = function(){
                        div.style.display='none';
            }
                    document.body.appendChild(div);
            }else{
                        div.style.display='block';
            }
            return div;
        }
})();
document.getElementById('loginBtn').onclick = function(){
        var loginDiv = createLoginDialog();
}

抽象出JavaScript單例模式表達

實際上,對於js單例模式最核心的邏輯就是app

var obj;
if(!obj){
    obj = XXX;
}

而對於以上最後寫出的建立代碼,也不盡完美,由於它違反了設計模式中的單一職原則。即建立對象和管理單例的邏輯都放在一個類的內部。
據此,咱們能夠剝離出建立單例模式的方法性能

var getSingleton = function(fn){
            var result;
            return function(){
                return result || (result = fn.apply(this,arguments));
            }
        }

最終在這個方法下實現代碼:this

var createLoginDialog = function(){
            var div = document.createElement('div');
            div.innerHTML='登陸懸浮框';
            var closeBtn = document.createElement('button');
            closeBtn.innerHTML = 'X';
            div.appendChild(closeBtn);
            closeBtn.onclick = function(){
                div.style.display='none';
            }
            document.body.appendChild(div);
            return div;
        }
var getSingleton = function(fn){
            var result;
            return function(){
                return result || (result = fn.apply(this,arguments));
            }
        }
var createSingletonLogin = getSingleton(createLoginDialog);
document.getElementById('loginBtn').onclick = function(){
            var loginDiv = createSingletonLogin();
            loginDiv.style.display = 'block';
}
相關文章
相關標籤/搜索