JavaScript 設計模式 之旅

設計模式開篇
日常開發中,我們都很注重開發技巧,好的開發 技巧可以事半功倍得解決此刻的問題。
那麼這些技巧如何來得呢?
我的了解: 經過不斷踩坑,解BUG,總結出來一些處理對應問題解決方案,這就所謂的
技巧
。
說起設計模式,其實我們日常開始中也經常用到,隻是你不知道用的
對應的
解決方案方案
.
設計模式名稱
學習設計模式的作用
在軟體設計中,模式是一些經過了大量實際項目驗證的優秀解決方案。熟悉這些模式的程式員,對某些模式的了解也會自然的形成條件反射。當遇到合适的場景出現時,可以快速找到對應的模式來處理目前的問題。
單例模式
定義: 保證 類 僅有,并可以全局通路這個
一個執行個體
執行個體
全局變量
不是 單例模式,但是在JavaScript 中, 我們經常把單例模式當作全局變量使用。
因為它滿足單例模式的兩點:
- 建立的全局變量是獨一無二的
- 它可以全局通路這個變量執行個體
// login.js
var loginInfo = {
username: '',
token: '',
.......
}
//login.vue
import logins from './login.js'
logins.name = this.username
但是它也有缺點,容易造成命名空間污染。
定義的
, 會覆寫掉之前定義的
全局變量多了
,這樣會造成不必要的
全局變量
BUG
如何處理命名空間污染呢?
如何處理呢?
- 1.使用命名空間
- 2.使用閉包封裝私有變量
命名空間
對象自變量的形式:
// login.js
export default var loginInfo = {
names:'' ,
token: '',
setName: function (name) {
this.names = name
},
getName: function () {
return this.name
}
}
//login.vue
import logins from './login.js'
logins.token = this.token
使用閉包封裝私有變量
把一些變量封裝在閉包内部,隻暴露一些接口跟外界通信。
外界是通路不到 内部定義的私有變量的,這樣就避免了全局指令污染。
var user = (function () {
//外界是通路不了 _name _age
var _name = '張三',
_age = 22;
return {
//這塊留給外界通信用
getUserInfo: function () {
console.log(`姓名為:${_name},年齡為:${_age}`)
}
}
})()
user.getUserInfo()
通用的惰性單例模式
在該執行的情況下,執行操作步驟 / DOM
優點: 節約了性能。
場景1
有時候,例如登陸彈窗,在加載首頁的同時,它會渲染這個頁的全部
DOM
,如果首頁DOM 内容多,加載速度也會相應的很慢,有很多不需要DOM提前渲染。
這時,可以通過惰性單例模式來解決此問題,例如單擊了登陸按鈕,才會建立登陸彈窗的DOM,并且記錄此次點選狀态,如果下次還要打開,隻是更改 DOM 的
的
style
屬性即可。 這樣節約了首頁加載時間,提升頁面性能。
display
// 定義全局通用單例模式
var getSingle = function (fn) {
var result;
return function () {
return result || (result = fn.apply(this, arguments));
}
}
// 建立登陸視窗
var createLoginLayer = function() {
var div = document.createElement('div')
div.innerHTML = '登陸框'
div.style.display = 'none'
document.body.appendChild(div)
return div
}
// 建立單例模式 登陸框
var createSingleLoginLayer = getSingle(createLoginLayer);
document.getElementById('btn').onclick = () => {
// 擷取單例模式中 傳回得登陸框
var loginLayer = createSingleLoginLayer();
// 改變樣式
loginLayer.style.display = 'block'
}
場景2
建立唯一的 iframe
用于加載第三方頁面
var createSingleIframe = getSingle( function() {
var iframe = document.createElement('iframe');
document.body.appendChild(iframe)
return iframe
})
document.getElementById('redirect').onclick = () => {
var iframeLayer = createSingleIframe();
iframeLayer.src = 'http://www.baidu.com'
}