JavaScript 全攻略:克服 JS 的奇怪部分 - 物件與函數 - 閉包(1)

探討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也不會這麼難了。

參考資料:

https://www.udemy.com/javascriptjs/learn/v4/overview