每日挑戰,從Javascript面試題目了解一些你可能忽略的概念 – Day12

tags: ItIron2021 Javascript

前言

昨天我們快速帶過閉包的概念,俗話說打鐵要趁熱,不吃飯會肚子餓(?) 馬上來道題目練習吧!

本日題目與解釋

請你寫一個mul函數,這個函數會有以下的輸出結果

console.log(mul(2)(3)(4)) // 24
console.log(mul(4)(3)(4)) // 48

防雷圖又來囉! 有朋友居然跟我說這才是每天文章的亮點😒

thinking-day12

題目不算困難,主要是要先經過一些拆解,我們知道在變數後加上()是呼叫函數的辦法,那也就表示

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

總結

  • 了解currying背後其實是透過閉包的概念達成

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s