定義: 保證一個對象(類)僅有一個實例,並提供一個訪問它的全局訪問點; 實現原理: 利用閉包來保持對一個局部變數的引用,這個變數保存著首次創建的唯一的實例; 主要用於: 全局緩存、登錄浮窗等只需要唯一一個實例的時候; Part1、命名空間的管理員開發中經常會遇到不同的人定義的變數使用的單詞可能會重覆 ...
定義:
保證一個對象(類)僅有一個實例,並提供一個訪問它的全局訪問點;
實現原理:
利用閉包來保持對一個局部變數的引用,這個變數保存著首次創建的唯一的實例;
主要用於:
全局緩存、登錄浮窗等只需要唯一一個實例的時候;
Part1、命名空間的管理員
開發中經常會遇到不同的人定義的變數使用的單詞可能會重覆,此時就需要用到命名空間來約束每個人定義的變數來解決這類問題。比如小明的代碼,他可以定義一個xiaoZhang的空間。同樣,我們平時使用的vue定義use()方法我們可以通過vue.use()來訪問
假如小張想實現這樣一個效果,點擊按鈕正方形的背景變成紅色
<style>
.squareStyle {
width: 100px;
height: 100px;
background-color: yellow;
}
</style>
<body>
<button id="btn">變黃</button>
<div id="square" class="squareStyle"></div>
</body>
<script>
var Zhang = {
a: function (id) {
return document.getElementById(id)
}, //獲取正方形
b: function (id, key, value) {
this.a(id).style[key] = value
} //這裡為什麼用this?a,b方法都在單例對象Zhang 中,而當前對象中的this指代當前對象,所以我們還可以在b方法中通過this.a()來使用Zhang單例對象中的a方法
} //創建空間
document.getElementById('btn').onclick = function () {
Zhang.b('square', 'backgroundColor', 'red')
}
</script>
this在javascript中的運用詳細可以看https://www.jianshu.com/p/041c683f6031這篇文章
Part2、惰性單例
需要的時候才被創建對象實例,就是需要的時候才動態調用,而不是頁面載入好的時候就創建
方式一:頁面載入好的時候調用,只不過是隱藏狀態
var createLoginAlert = (function () {
console.log('創建了')
var div = document.createElement('div')
div.innerHTML = '我是彈窗'
div.style.display = 'none'
document.body.appendChild(div)
return div
})() //自執函數
document.getElementById('btn').onclick = function () {
createLoginAlert.style.display = 'block' //點擊的時候顯示
}
現在有個問題,就是用戶可能只是瀏覽頁面,並不需要彈窗內容,接下來方式二是對方式一的優化
方式二:點擊的時候才創建實例
<button id="btn">提交</button>
var createLoginAlert = function () {
var div = document.createElement('div')
div.innerHTML = '我是彈窗'
div.style.display = 'none'
document.body.appendChild(div)
return div
}
// 點擊提交時候創建實例
document.getElementById('btn').onclick = function () {
var popUp = createLoginAlert()
popUp.style.display = 'block'
}
每一次點擊的時候重新創建實例,雖然我們可以在點擊浮窗上的關閉按鈕時(此處未實現)把這個浮 窗從頁面中刪除掉,但這樣頻繁地創建和刪除節點明顯是不合理的,也是不必要的
方式三:用一個變數來判斷是否已經創建過登錄浮窗,沒有-->創建,有-->復用
var createLoginAlert = (function () {
var div; //變數
return function () {
if (!div) {
console.log('沒有DIV')
div = document.createElement('div')
div.innerHTML = '我是彈窗'
div.style.display = 'none'
document.body.appendChild(div);
return div
}
return div
}
})()
// 點擊提交時候創建實例
document.getElementById('btn').onclick = function () {
var popUp = createLoginAlert()
popUp.style.display = 'block'
}
Part 3 對象池
對象池維護一個裝載著空閑對象的池子,如果需要對象的時候,不是直接new,而是從對象池中取出,如果對象池中沒有空閑對象,則新建一個空閑對象。對象池技術的使用非常廣泛,http連接池和資料庫連接池都是其代表。在web前端中,對象池使用最多的使得DOM有關的操作。
對象池的實現
var objectPoolFactory=function(createObjFn){
var pool=[],
create=function(){
var obj=pool.length>0?pool.shift():createObjFn.apply(this,arguments);
return obj;
},
recover=function(obj){
pool.push(obj);
};
return {
create:create,
recover:recover,
};
};
Part 4、 變數緩存
如果ret不是基本變數,而是一個對象,則可以用來實現緩存,在jQuery的源代碼中有很多這樣的例子。
var cache={};//一般定義為一個全局變數
var tmp=cache[key]||fn(key);
查閱文獻:
《javascript設計模式》《javascript設計模式及開發實踐》
分享文檔:
鏈接: https://pan.baidu.com/s/1Twpu1hM2YaPsNEqgiXsAZQ 密碼: i8jf
僅限知識分享,請勿商業使用,謝謝