iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 20
0
Modern Web

一步一腳印-紮紮實實學es6系列 第 20

閉包(2) 執行環境的現象

昨天提到的問題
這個n 應該是離開了作用域就會被回收
為什麼每次執行kk() 看起來就像個全域變數一樣
可以累加計算呢?

var FatherFunc=()=>{
    var n=10;
    var sonFunc=()=>{
        n++;
        console.log(n);
    }
	return sonFunc;
}
var kk=FatherFunc();
kk();
kk();

這是因為在內層的執行環境(execution context)被有其他變數所引用
而這個FatherFunc又有內函數的變數
變成了相互引用的關係,所以都不會被回收
所以我們可以在執行的上下文(執行環境的)之中,存取到函數內的區域變數

什麼意思呢?
我們一步一步來看
考慮以下狀況
如果沒有一個變數來接FatherFunc(),
就是沒有賦值給其他變數的話
變成單純呼叫
這樣是否就會被垃圾回收機制所回收呢?
我們來實驗看看

var FatherFunc=()=>{
    var n=10;
    var sonFunc=()=>{
        n++;
        console.log(n);
    }
	return sonFunc;
}
FatherFunc()(); //直接呼叫
FatherFunc()();

可以看到2次執行結果都是11
https://ithelp.ithome.com.tw/upload/images/20181020/20110579ZBsZ5aYRD2.png

為什麼會這樣呢
這是由於在FathcerFunc執行的時候
他的n 並不會被回收,因為有賦值給外面的kk()
但子函數sonFunc 他執行完,裡面的n++ 的這個n
執行完就被回收了
但是子函數裡面本來並沒有n 他的這個n 用 父函數的n
所以在return sonFunc 之後,這個n++ 的n 被改成 11
https://ithelp.ithome.com.tw/upload/images/20181020/20110579Sh5kb4rtGX.png
↑目前的FatherFunc()長這樣
而沒有賦值給一個變數的話(這邊是kk)
這個n 在執行後就會被回收

詳細執行環境的原理
我們來明天討論


上一篇
closure 閉包(1)
下一篇
非同步學習入門-消息隊列的執行順序
系列文
一步一腳印-紮紮實實學es630

尚未有邦友留言

立即登入留言