保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。設計模式
一個單一對象。好比頁面中有一個登錄按鈕,點擊後出現一個登錄彈窗,而這個彈窗是惟一的,無論按鈕點擊幾回,彈框只會被建立一次,那這個彈窗就適合單例模式
來建立。緩存
以上述應用場景爲例markdown
const createLoginModal = (function() { let div; return function() { if (div) return div; div = document.createElement("div"); div.innerHTML = "我是彈窗"; div.style.display = "none"; document.body.appendChild(div); }; })(); document.getElementById("loginBtn").onclick = () => { const loginModal = createLoginModal(); loginModal.style.display = "block"; }; 複製代碼
上面實現了一個可用的單例方法,可是無法通用。若是想再建立一個span
標籤的話,幾乎要把createLoginModal
照抄一遍。app
咱們須要把不變的部分(管理單例的邏輯)抽離出來,把建立對象的方法經過 fn
當成參數動態傳入getSingle
函數:函數
function getSingle (fn) { let result return function() { if (result) return result result = fn.apply(this, arguments) return result } 複製代碼
接下來用來建立彈窗的方法能夠用參數fn
的形式傳入getSingle
。代碼以下:oop
const createLoginModal = function() { const div = document.createElement("div"); div.innerHTML = "我是彈窗"; div.style.display = "none"; document.body.appendChild(div); return div; }; const createSingleLoginModal = getSingle(createLoginModal); document.getElementById("loginBtn").onclick = () => { const loginModal = createSingleLoginModal(); loginModal.style.display = "block"; }; 複製代碼
單例模式禁止經過除了特殊構建方法之外的任何方式來建立自身類對象。 該方法能夠建立一個新對象,但若是該對象已經被建立,則返回已有的對象。this
單例模式與全局變量不一樣,它保證類只存在一個實例。 除了單例類本身之外,沒法經過任何方式替換緩存的實例。spa