iT邦幫忙

2021 iThome 鐵人賽

DAY 13
0
自我挑戰組

追憶JS年華系列 第 18

Day-18 閉包

  • 分享至 

  • xImage
  •  

閉包(closure),即當使用高階函式(function中有function、function回傳function)時,可以將外層函式裡宣告的變數&值「包進來」=>保留到內層函式使用。

範圍鏈 Scope chain

閉包的本質,建立於範圍鏈(Scope chain)的設計之上。其中一種範圍鏈現象,就是前文『Day-12 函式與變數』 曾經提過的「函式變數未宣告,往外變全域」現象。完整
說明請另參考:
『[JavaScript] Javascript 的作用域 (Scope) 與範圍鏈 (Scope Chain):往外找』

閉包範例

例:setTimeout與加法器

//  外層函式 = a
function a() {
    var x = 123
    
    //  closure 閉包
    //  內層函式 = setTimeout
    setTimeout(() => {
        console.log(x)
    }, 1000)
}
a()

x 本來會隨著外層的泡泡破掉而消失,但 JS 卻能把 x 一起帶到 WebAPI 排隊。

閉包過程

  1. 一開始 JS 會先建構全域執行環境、分配記憶體給函式及變數、建構函式及宣告變數&賦值。
  2. function a & setTimeout 、 var x = 123 及 console.log(x) 的 x 都會被建立起來。(console.log(x) 的 x 會因為 scope chain 的關係先在內層找有沒有宣告 x ,因為找不到所以往外層找,最後找到 var x = 123,所以內層的 x 會指向外層的 123)
  3. 再來會建構 function 的執行環境以及執行程式碼。
  4. 呼叫 function a ,建構 a 的執行環境,將 x 儲存在 a 的執行環境。
  5. 準備執行 setTimeout ,外層 a 的泡泡破掉,此時 var x = 123 因為一開始有被分配到記憶體,所以還會留在原地,不會跟著泡泡破掉而消失。
  6. 執行 setTimeout,x 能夠指向外層的 123,不會變成not defined。1.

意者另可參考:『所有的函式都是閉包:談 JS 中的作用域與 Closure』


上一篇
Day-17 同步、非同步與事件循環
下一篇
Day-19 This
系列文
追憶JS年華30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言