在看過前面有關於closure的說明後,不知道你對於JavaScript中closure的概念是不是更清楚了?
[筆記] 談談JavaScript中closure的概念 -- Part 1
[筆記] 談談JavaScript中closure的概念 -- Part 2
[筆記] 談談JavaScript中closure的概念 -- Part 3
在這篇文章中,我們來看看在Framework中可以怎麼樣使用closure這樣的概念。
讓我們先來看下面這段程式碼,
我們先建立了一個makeSayHi的function,而這個function會回傳另一個匿名函式 return function(name){...} ,這個匿名函式則會根據makeSayHi的參數language來回傳不同的內容:
接著,我們分別將兩個不同language參數而回傳的function存成兩個變數,並且加以呼叫:
看過前幾個Closure概念後,你是不是可以知道,這樣會ouput出什麼樣的結果呢?
結果如下,和你想的一樣嗎?
解讀程式
讓我們再次試著了解這段程式的內容。
首先,由於hoisting的緣故,makeSayHi( ), SayHiEnglish, SayHiChinese會先被儲存在記憶體中,接著才開始逐行執行程式碼:
當程式執行到 var SayHiEnglish = makeSayHi('en') 時,makeSayHi的execution context被建立,同時將變數language的值'en'儲存在這個execution context中
接著,會回傳makeSayHi裡面的匿名函式,並儲存到SayHiEnglish這個變數中。執行完後makeSayHi的execution context就抽離了,但language參數的值"en"仍然被儲存在記憶體中:
接著,程式會執行到 var SayHiChinese = makeSayHi('zh') ,這時候我們會再次執行makeSayHi這個函式,雖然執行的是同樣makeSayHi這個函式,但實際上會產生新的一個execution context,也就是說,你每執行一次函式,就會產生一個新的execution context。
接著,一樣會將回傳的匿名函式儲存在SayHiChinese中,makeSayHi的execution context再次抽離,並留下language的參數:
將函式都儲存到變數後,會執行 SayHiEnglish('PJCHEN') ,這時,SayHiEnglish會被執行,並代入name變數的值"PJCHEN",這時候在記憶體中有兩個language參數的值被儲存著,一個是zh, 一個是en,而JavaScript引擎會自己找到它所對應的參數值,並形成所謂的closure。
同樣的情形會在程式執行到 SayHiChinese('PJCHEN') 發生,於是再次形成了一個新的closure。
整個程式執行的流程大概就是這樣子。這裡的重點在於每執行一次函式,就會產生一個新的execution context,而且即使有多個參數值被儲存在記憶體中,JavaScript引擎會自己找到屬於該execution context的變數。
程式範例
function makeSayHi(language){ return function(name){ if(language === 'en'){ console.log('Hello ' + name); } if(language === 'zh'){ console.log('你好 ' + name); } } } var SayHiEnglish = makeSayHi('en'); var SayHiChinese = makeSayHi('zh'); SayHiEnglish('PJCHEN'); SayHiChinese('PJCHEN');→回到此系列文章目錄
資料來源:[Udemy] JavaScript: Understanding the weird part - Framework Aside: Function Factories
頁首圖片來源:SitePoint
頁首圖片來源:SitePoint
0 意見:
張貼留言