如果想在所有的地方都能訪問同一個變數,那麼應該怎麼辦呢?
在實踐中這種場景很多,比如全域性的狀態管理。
但前面我們介紹過,在實際開發中,不要輕易使用全域性變數,那又該怎麼辦呢?模組化的思維能夠幫助我們解決這個問題。
模組化開發是目前最流行,也是必須要掌握的一種開發思路。而模組化其實是建立在單例模式基礎之上的,因此模組化開發和閉包息息相關。
目前流行的模組化開發思路,無論是require,還是ES6的modules,雖然實現方式不同,但是核心思路一樣。因此為了方便大家理解模組化的思維,這裡就以建立在函式自執行基礎上的單例模式為例,一起來感受一下模組化開發的魅力。
第一,請記住:每一個單例就是一個模組。
其實,你也知道,每一個檔案也是一個模組。而這裡把每一個單例模式假想成一個單獨的檔案即可。定義一個模組,而變數名就是模組名。
var module_test = (function() {
})();複製程式碼
第二,每一個模組要想與其他模組互動,則必須有獲取其它模組的能力,例如requirejs中的require與ES6modules中的import。
//require
var $ = require(`jquery`);
//es6 modules
import $ from `jquery`;複製程式碼
第三,每一個模組都應該有對外的介面,以保證與其他模組互動的能力。這裡直接使用return返回一個字面量物件的方式來對外提供介面。(你可以回顧一下現在那些模組的匯出是多麼便捷)
var module_test = (function() {
...
return {
testfn1: function() {},
testfn2: function() {}
}
})();複製程式碼
現在我們結合一個簡單的案例來走一遍模組化開發的流程。這個例子想要實現的功能是每個一秒,body的背景色就隨著一個數字的遞增在固定的三種顏色之間切換。
(1)首先建立一個專門用來管理全域性狀態的模組。這個模組中有一個私有變數儲存了所有的狀態值,並對外提供了訪問與設定這個私有變數的方法,程式碼如下:
var module_status = (function() {
var status = {
number: 0,
color: null
}
var get = function(prop) {
return status[prop];
}
var set = function(prop,value) {
status[prop] = value;
}
return {
get,
set
}
})();複製程式碼
(2)在來建立一個模組,這個模組專門負責body背景顏色的改變。
var module_color = (function() {
//假裝用這種方式執行第二步引入模組
//類似 import state from `module_status`;
var state = module_status;
var colors = [`yellow`,`#ccc`,`red`];
function render() {
var color = colors[state.get(`number`) % 3];
document.body.style.backgroundColor = color;
}
return {
render
}
})();複製程式碼
在這個模組,引入了狀態管理的模組,並且將顏色的管理與改變方式都定義在該模組中,因此在使用時我們只需呼叫render方法就可以了。
接下來我們還需要建立另外一個模組來負責顯示當前的number的值,用於參考對比。
var module_context = (function() {
var state = module_status;
function renderNumber() {
document.body.innerHTML = `now number is` + state.get(`number`);
}
return {
renderNumber
}
})()複製程式碼
這些功能模組都建立完畢後,最後我們只需建立一個主模組即可。這個主模組的目的就是藉助功能模組,來實現我們想要的效果。
var module_main = (function() {
var state = module_status;
var color = module_color;
var context = module_context;
setInterval(function() {
var newNumber = state.get(`number`) + 1;
state.set(`number`,newNumber);
color.render();
context.renderNumber();
},1000)
})();複製程式碼
好了,整一個模組化就完成了。你可以將整段程式碼插入到一個HTML檔案script標籤下即可看到展示效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change yourself</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
<script>
var module_status = (function() {
var status = {
number: 0,
color: null
}
var get = function(prop) {
return status[prop];
}
var set = function(prop,value) {
status[prop] = value;
}
return {
get,
set
}
})();
var module_color = (function() {
//假裝用這種方式執行第二步引入模組
//類似 import state from `module_status`;
var state = module_status;
var colors = [`yellow`,`#ccc`,`red`];
function render() {
var color = colors[state.get(`number`) % 3];
document.body.style.backgroundColor = color;
}
return {
render
}
})();
var module_context = (function() {
var state = module_status;
function renderNumber() {
document.body.innerHTML = `now number is` + state.get(`number`);
}
return {
renderNumber
}
})();
var module_main = (function() {
var state = module_status;
var color = module_color;
var context = module_context;
setInterval(function() {
var newNumber = state.get(`number`) + 1;
state.set(`number`,newNumber);
color.render();
context.renderNumber();
},1000)
})();
</script>複製程式碼
執行以上完整程式碼,就可以看到如果效果啦
當然它是每個一秒變一次的….
這些都是我以往的學習筆記。如果您看到此筆記,希望您能指出我的錯誤。有這麼一個群,裡面的小夥伴互相監督,堅持每天輸出自己的學習心得,不輸出就出局。希望您能加入,我們一起終身學習。歡迎新增我的個人微訊號:Pan1005919589