前言:菜雞也有夢想,而我的夢想就是進一個真正的網際網路大廠。以前學習的時候沒有系統的整理,從今天開始要保持每週寫部落格的習慣,希望自己可以有所成長。為了培養程式設計思維,決定從設計模式開始寫起。我是通過讀《Javascript設計模式與開發實踐》來學習設計模式,並且將知識點和收穫記錄在部落格中。
此文僅記錄本人閱讀《JavaScript設計模式與開發實踐》的知識點與想法,感謝作者曾探大大寫出這麼好的一本書。如有冒犯,請聯絡本人:markcoder@outlook.com處理,請大家購買正版書籍。
1. 單例模式介紹
單例模式的定義是:保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點。
比如登入框和購物車就適合用單例模式。
2.程式碼實現
要點:用一個變數來標誌當前是否已經為某個類建立過物件,如果是,則在下一次獲取該類的例項時,直接返回之前建立的物件。
const Singleton = function (name) {
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function () {
alert(this.name);
};
Singleton.getInstance = function (name) {
if (!this.instance) { // 如果之前沒有建立過例項
this.instance = new Singleton(name);
}
return this.instance;
};
let a = Singleton.getInstance('event1');
let b = Singleton.getInstance('event2');
console.log(a === b); // true
複製程式碼
或者
const Singleton = function (name) {
this.name = name;
};
Singleton.prototype.getName = function () {
alert(this.name);
};
Singleton.getInstance = (function () {
let instance = null;
return function (name) {
if (!instance) { // 如果之前沒有建立過例項
instance = new Singleton(name);
}
return instance;
}
})();
let a = Singleton.getInstance('event1');
let b = Singleton.getInstance('event2');
console.log(a === b); // true
複製程式碼
ES6實現
class Singleton {
login () {
console.log(login)
}
}
Singleton.getInstance = (function () {
let instance;
return function () {
if (!instance) {
instance = new Singleton();
}
return instance;
}
})();
let a = Singleton.getInstance();
let b = Singleton.getInstance();
console.log(a === b); // true
複製程式碼
Singleton類的使用者必須知道通過 Singleton.getInstance 這個方法來獲取物件,而不是通過 new XXX 的方式。
3.透明的單例模式
let CreateDiv = (function () {
let instance;
let CreateDiv = function (html) {
if (instance) {
return instance;
}
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function () {
let div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
return CreateDiv; // 返回真正的構造方法
})();
let a = new CreateDiv( 'event1' );
let b = new CreateDiv( 'event2' );
console.log ( a === b ); // true
複製程式碼
通過匿名函式返回真正的建構函式 CreateDiv 。假如某天我們要在頁面中建立更多的div,就需要修改建構函式,所以程式碼仍然需要改進。
4.用代理實現單例模式
let CreateDiv = function (html) {
this.html = html;
this.init();
};
CreateDiv.prototype.init = function () {
let div = document.createElement('div');
div.innerHTML = this.html;
document.body.appendChild(div);
};
// 利用閉包將管理單例模式的邏輯放在了proxySingleton
let proxySingleton = (function () {
var instance;
return function (html) {
if (!instance) {
instance = new CreateDiv(html);
}
return instance;
}
})();
let a = new proxySingleton( 'sven1' );
let b = new proxySingleton( 'sven2' );
console.log ( a === b );
複製程式碼
5.使用單例模式的總結
- 模擬登入框
class Login {
constructor () {
this.state = 'hide'
}
show () {
if (this.state === 'show') {
return
}
this.state = 'show'
}
hide () {
if (this.state === 'hide') {
return
}
this.state = 'hide'
}
}
Login.getInstance = (function () {
let instance;
return function () {
if (!instance) {
instance = new Login();
}
return instance
}
})();
let login1 = Login.getInstance();
let login2 = Login.getInstance();
console.log(login1 === login2);
複製程式碼
- 無論引入多少次jQuery庫,全域性只有一個$
if (window.jQuery != null) {
return window.jQuery
} else {
// 初始化
}
複製程式碼
- vuex和redux的store