iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 19
0
自我挑戰組

前端工程師的30份套餐系列 第 19

Day19- 閉包(一)

  • 分享至 

  • xImage
  •  

Closure這個詞有關閉、結束的意思,而閉包是JS一個重要觀念,非常難懂所以很多人不喜歡。

在JavaScript中每當函式被建立時,閉包就會被產生,是函式建立時就有的自然特性。雖然經常使用函式中的函式這樣的寫法,也就是巢狀函式的語法結構,是一種最常見、可被重複利用的閉包語法,但並不是只有巢狀函式才能產生閉包

函式可以

  1. 傳入其他函式作為傳入參數
  2. 當作另一個函式的回傳值
  3. 指定為一個變數的值

先來看看以下範例:
因為函式就是物件,所以可把它當成一個值回傳,

function data(text) {
    return function(name) {
        console.log(text+ '' + name)
    }
}

但這時要如何呼叫函式? 雖然這看起來有點怪
呼叫一個回傳函式的函式data時,同時呼叫那個被回傳的函式(阿 好像在繞口令)

data('hello')('joyce');  
//打開console就可以看到:
//hello joyce

function data(text) {
    return function(name) {
        console.log(text+ '' + name)
    }
}

//設定一個變數為函式的回傳值
var  sayHi = data('Hi')
//呼叫sayHi,執行這段,仍然可以執行
sayHi('Tommy')  //Hi Tommy

當在執行sayHi的時候 因為是閉包所以text參數在data函式被呼叫的時候
仍然可以被使用,

在執行這段函式時,是全域的執行環境
1.到了var sayHi = data這行時,呼叫了data
2.這時,新的執行環境被創造了
3.text參數被傳入到data的環境裡
4.然後再回傳一個新的物件函式
5.回傳之後,data的執行環境就離開了執行堆
6.這個data執行堆就不見了

但這裡有個問題!
每個執行環境都有自己的記憶體空間,參數和函式都被創造在裡面,那當執行環境沒了之後記憶體空間會怎麼樣呢?在一般情況下,JS引擎會清除它,這動作稱為垃圾回收,但是當執行環境結束時,記憶體空間仍然存在即使執行環境已經沒了但它還在記憶體某處。

也就是說:
data已經沒了執行環境,但在記憶體中還在,只是不在執行堆裡,但是執行環境可以把它的外部變數關住、包住,所以可以取用到的現象稱為閉包

所以JS永遠會確保無論我在執行哪個函式,都能取用該要用到的變數是JavaScript重要且強大的特色

參考: udemy-克服 JS 的奇怪部分


上一篇
Day18-call()、apply()與bind()
下一篇
Day20-閉包(二)
系列文
前端工程師的30份套餐30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言