探討closure,並舉一些範例。
欲進入前,請先閱讀下列兩篇文章:
JavaScript 全攻略:克服 JS 的奇怪部分 - 執行環境與詞彙環境(4)
JavaScript 全攻略:克服 JS 的奇怪部分 - 執行環境與詞彙環境(5)
前言:
此為學JavaScript多少一定會碰壁的章節,所以在講closure之前,最好複習一下scope chain這個內容,會對closure比較好理解。
首先我們先來看一段程式碼:
function Greet(saySomething){
return function(name){
console.log(name +" say "+ saySomething)
}
}
var greet = Greet("hi");
greet("Scott");
執行結果如下:
經由 JavaScript 全攻略:克服 JS 的奇怪部分 - 執行環境與詞彙環境(4) 這個章節,我們可以知道,其實函數呼叫完之後就會被抽離出執行堆,所以其實我們今天在執行greet("Scott")這行的時候,應該是不會知道saySomething這個變數的,但是他卻可以找到...。
稍微解析一下整個程式碼在運行的過程
1.一開始會產生Global的execution context,並且做hoisting
2.執行到Greet()的時候,產生了一個execution context,裡面有變數saySomething
3.Greet()執行完畢,此execution context會被garbage collection,但,saySomething實際上不會被收走,而是存在記憶體裡面。
4.接著greet這個匿名函數執行,也創造了一個execution context
5.當此匿名函數要執行的時候,在找saySomething這個變數的時候,因為本身的execution context找不到,就透過scope chain找到了之前在記憶體中的saySomething
這種現象,我們就稱為closure,就算execution context沒有某些function了,但JavaScript就是可以找到對應的變數。
小結:
我個人認為,只要能清楚scope chain找變數的過程,其實closure也不會這麼難了。