ItIron2021
Javascript
昨天我們快速帶過閉包的概念,俗話說打鐵要趁熱,不吃飯會肚子餓(?) 馬上來道題目練習吧!
請你寫一個mul函數,這個函數會有以下的輸出結果
console.log(mul(2)(3)(4)) // 24
console.log(mul(4)(3)(4)) // 48
防雷圖又來囉! 有朋友居然跟我說這才是每天文章的亮點?
題目不算困難,主要是要先經過一些拆解,我們知道在變數後加上()是呼叫函數的辦法,那也就表示
mul => 這玩意是個函數(廢話)
mul(2) => 這玩意也是個函數
mul(2)(3) => 這玩意還是個函數
也就是說,你傳入第1個 & 第2個參數時都會回傳一個函數,這不就是昨天提到的function return function嗎? 而每次你都能傳入一個參數,這麼一想結構就簡單多囉!
先從第一步開始吧,寫一個mul函數並接受一個參數,且我們知道它會回傳另一個接受一個參數的函數
function mul(x) {
return function (y) {
}
}
看到這邊我想你知道接下來要怎麼接了,沒錯,就是再串一層就好! 只是記得最後就不是再回傳一個函數,而是回傳最終相乘的結果囉!
function mul(x) {
return function (y) {
return function (z) {
return x * y * z
}
}
}
console.log(mul(2)(3)(4)) // 24
console.log(mul(4)(3)(4)) // 48
也許你能輕易寫出這個函數,但你有意識到關鍵嗎? 函數一旦執行後就會從main stack中跳出,裡面的變數自然也不存在了,為什麼內層的函數仍有x & y的值呢? 沒錯,這樣內部函數存取外部環境的值就是非常典型的閉包! 藉由閉包的特性我們才能達成這樣的函數(順帶一提,mul(x)(y)(z)這樣的玩意其實有個專有名詞currying,有興趣可以自己去探究,沒什麼特別的)
如果是面試碰到這樣的題目,寫出上方的寫法基本上就沒問題了,但確實可以透過箭頭函數讓它變得更精簡一些,若以下看不懂...那就等將近Day20講到箭頭函數的時候吧:D
const mul = x => y => z => x * y * z
console.log(mul(2)(3)(4)) // 24
console.log(mul(4)(3)(4)) // 48
閉包(closure)、currying
本文章同步發布於個人部落格,有興趣的朋友也可以來逛逛~!