[JavaScriptWeird]No.36 框架小叮嚀: Function Factories

前言

前面提到了閉包,也講解了一些典型的範例,而閉包還有很多有用的地方。在這篇文章中,我們會談到如何利用閉包來建立函式工廠 (Function Factories),讓程式的撰寫上能更靈活,減少累贅的程式碼,這個技巧常常可在一些知名框架內看到。

Function Factories

我們在重載函式那一篇知道,可以有一些做法讓函式可以在不同情況下被不同的預設參數呼叫。因為我們已經了解閉包,所以我們將要使用閉包的概念讓這個範例更完善。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function makeGreetFactory(languaue){  
return function(firstName, lastName){
if(languaue === 'en'){
console.log('Hello ' + firstName + ' ' + lastName);
}
if(languaue === 'es'){
console.log('Hola ' + firstName + ' ' + lastName);
}
}
}

var greetEnglish = makeGreetFactory('en');
var greetSpanish = makeGreetFactory('es');
greetEnglish('Tony', 'Doe');
greetSpanish('Tony', 'Doe');

  • 建立一個會回傳函式的 makeGreetFactory 函式,並可以帶入 languaue 參數。
  • 被回傳的匿名函式可以帶入 firstNamelastName 並且依據 languaue 有不同的打招呼方式。

注意到不同的地方了嗎?

原本我們是將 languaue 傳入到匿名函式內,這次改成傳到外部函式,利用閉包的概念去完成。

  • 接著宣告 greetEnglish 變數,指向 makeGreetFactory 函式並帶入 languaue 的參數值 「en」。

    • 當 JavaScript 運行到這一行時,每當 makeGreetFactory 被呼叫就會建立一個執行環境,以這個執行環境來說, languaue 為 「en」。
  • 同理,宣告 greetSpanish 變數,呼叫 makeGreetFactory ,此時又建立一個執行環境,以這個執行環境來說, languaue 為 「es」。

    • 因此,當我呼叫 greetEnglish() 時,因為閉包的關係,即使 makeGreetFactory 函式不再執行堆裡,變數 languaue 仍可被取用。

greetEnglish() 對應的閉包範圍 languaue 值為「en」
同理 greetSpanish() 對應的閉包範圍 languaue 值為「es」

白話說 Function Factories

以這個例子來說, makeGreetFactory 函式就像一個箱子工廠,而傳入的 languaue 可以理解成不同種類的箱子。

然後我跟這個工廠說,我要一個種類為「en」的箱子,於是我得到了一個在外部寫有「en」字樣的箱子,並且裡面裝有一個會參考到這個箱子外部寫了什麼種類的函式

使用圖例幫助了解閉包範圍

最後要強調的是,每當呼叫函式,函式會得到專屬於它的執行環境,然而在這個執行環境內被創造的函式會指向這個執行環境(注意創造不等於呼叫)。

0%