艾草:「昨天教你原理,今天我們實際來實作這個術式吧!」
「好~~」
艾草:「來!發動前要唸咒語,霹靂卡霹靂拉拉波波力那貝貝魯多!」
「這也太羞恥了吧!真的要嗎...霹靂...波波..⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄.」
艾草:「嗯,很好,很棒,大聲一點!」
「等等,我剛剛看妳發動不用唸呀?」
艾草:「嘿嘿 A____A !」
上一篇我們介紹了閉包的原理後,這篇來介紹關於閉包的實作方式。
假設今天想要計算魔力總量,學習入門魔法總量(mana)增加 100 、中階魔法總量(mana)增加 200 。
目前狀態:
function addMana() {
let myMana = 100;
return function (mana) {
myMana += mana;
return myMana;
}
}
//將 shannonMana 指向 addMana()
let shannonMana = addMana();
//透過 shannonMana() 執行內層函式
console.log(shannonMana(100));//200
console.log(shannonMana(100));//300
console.log(shannonMana(200));//500
addMana
函式,並在函式內定義變數魔力總量初始值 myMana
為 100addMana
內回傳一個內層函式,內層函式內會取用外層 myMana
變數,並加入參數為新增的魔力總量 mana
shannonMana
並使其指向 addMana()
函式shannonMana()
並傳入參數執行 內層函式的魔力總量新增像這樣就算出了,目前魔力總量為 500 !
當然閉包能做到的不止如此,今天如果有多人都想算魔力總量,還可以這樣做!
因為今天有多人了,每人的魔力總量初始值不一,所以先在 addMana()
函式內新增參數 initialMana
,讓大家都可以傳入魔力總量初始值。
function addMana(initialMana) {
let myMana = initialMana;
return function (mana) {
myMana += mana;
return myMana;
}
}
首先幫第一位來賓 Vivian 計算魔力總量:
let vivianMana = addMana(250); //傳入初始值 250
console.log(vivianMana(100));//350
console.log(vivianMana(200));//550
console.log(vivianMana(200));//750
透過這個方式就能計算出 Vivian 目前魔力總量為 750 。
此時來了第二位來賓 Ami ,來幫他計算魔力總量:
let amiMana = addMana(800); //傳入初始值 800
console.log(amiMana(100));//900
console.log(amiMana(200));//1100
像這樣就可以算出 Ami 魔力總量為 1100 。
觀察上方兩個案例,流程基本如下:
addMana()
函式,並於函式內依情境傳入初始魔力總量 initialMana
()
於內層函式傳入參數新增的魔力總量 mana
可以發現,透過將外層函式賦予給不同變數,再透過變數去呼叫內層函式,能達成計算多人魔力總量的結果。
魔力總量除了新增之外,也可能會有減少的情況,例如好一陣子沒碰到 JavaScript 魔法後,根本不知道自己當初寫了啥等。
為了因應多種情境,可以這樣改寫程式碼:
function calcMana(initialMana) {
let myMana = initialMana;
return {
addMana: function (mana) {
myMana += mana;
return myMana;
},
minusMana: function (mana) {
myMana -= mana;
return myMana;
}
}
}
addMana()
、 minusMana()
負責計算增加與減少。如果今天想計算來賓 Ann 的魔力總量:
let AnnMana = calcMana(500); //傳入初始值 500
console.log(AnnMana.addMana(200));//700
console.log(AnnMana.addMana(200));//900
console.log(AnnMana.minusMana(100));//800
像這樣透過變數呼叫內層函式後,使用點記法選取物件屬性,並執行對應函式,就可以計算多種條件!
JavaScript 核心篇(六角學院)
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Closures
https://wcc723.github.io/javascript/2017/12/13/javascript-closure/