iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 18
0
Modern Web

30天入門JavaScript系列 第 18

【Day 18】閉包 closure

  • 分享至 

  • xImage
  •  



在講閉包前,先補充一點執行環境的東西。

之前講到當一個執行環境產生時,會建立自己的區域變數,
會建立一個叫作Activation object(找不到中文翻譯 執行中物件?)的物件,
裡面除了有區域變數跟函式外,還有參數跟引數。


所以一個函式執行環境內,大概會有這些東西
https://ithelp.ithome.com.tw/upload/images/20200918/20129836ErBDaPx22w.png



好了回到閉包,一樣先來看維基對閉包的介紹

在電腦科學中,閉包(英語:Closure),又稱詞法閉包(Lexical Closure)或函式閉包(function closures),是在支援頭等函式的程式語言中實現詞法繫結的一種技術。閉包在實現上是一個結構體,它儲存了一個函式(通常是其入口位址)和一個關聯的環境(相當於一個符號尋找表)。環境裡是若干對符號和值的對應關係,它既要包括約束變數(該函式內部繫結的符號),也要包括自由變數(在函式外部定義但在函式內被參照),有些函式也可能沒有自由變數。閉包跟函式最大的不同在於,當捕捉閉包的時候,它的自由變數會在捕捉時被確定,這樣即便脫離了捕捉時的上下文,它也能照常執行。






......

https://ithelp.ithome.com.tw/upload/images/20200918/20129836bqcITz1q19.jpg

還是來看程式吧

var a = '全域變數';

function makeFunc() {
  var a = '區域變數';

  return function () {
    return a;
  };
}

var func = makeFunc();

console.log(func());



makeFunc會宣告一個函式(return a)後回傳,
makeFunc回傳的函式給func,這時後印出呼叫func回傳的結果(a),
照範圍鍊來看,a應該參照到makeFunc內的區域變數a,
makeFunc的執行環境早已消滅,區域變數應該都被消去了,此時"理論"上會參照到全域變數a

像這樣
https://ithelp.ithome.com.tw/upload/images/20200918/20129836QRu9Yum3Tm.png

但是實際的結果
https://ithelp.ithome.com.tw/upload/images/20200918/20129836tph5Y2JDJE.png


makeFunc都消滅了區域變數a卻還在,這是為什麼呢?

其實當makeFunc內的函式被宣告時,會記住範圍鍊上的區域變數,
即使原本區域變數的執行環境消滅,只要這個函式還在就能存取到a變數。

像這樣子,區域變數a被保留著,此時此變數a只有func函式可以訪問得到,沒辦法用其他方式存取
https://ithelp.ithome.com.tw/upload/images/20200918/20129836Y8It8nFP9t.png


講那麼多,所以閉包到底是甚麼?



https://ithelp.ithome.com.tw/upload/images/20200918/201298361pI1buFbiw.png


上一篇
【Day 17】範圍 scope
下一篇
【Day 19】利用閉包達成私有變數、記憶化
系列文
30天入門JavaScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言