0%

JS 核心觀念筆記 - 閉包基本認識、工廠模式與私有方法

core

閉包定義

Closure 這個字詞是由 Close 與字尾 -ure 所構成,-ure 有動作、進結果的意思,如果 close 是關閉的意思,clousure 就是關閉的結果或動作,它可以作為名詞或動詞使用,中文有封閉終止結束的意思。

在 JavaScript 中每當函式被建立時,一個閉包就會被產生,閉包是一個函式建立時的就有的自然特性。

直接呼叫內層函式

閉包的概念就是呼叫函式中的函式,以下方程式碼為例,

  • 宣告一個函式,裡面做兩件事。
  • 宣告一個變數。
  • 回傳的值帶入內部的函式。
  • 內部的函釋內容為變數 myMoney 等於 myMoney - price(帶回外部的參數到內部函式的值)。
  • 然後再回傳到 myMoney。
1
2
3
4
5
6
7
8
9
10
function buyItem() {
var myMoney = 1000;
return function (price) {
// 這裡就是一個閉包,不過目前只會使用一次
myMoney = myMoney - price; //myMoney = 1000 -100,回傳結果的值等於 myMoney
return myMoney;
};
}
let balance = buyItem()(100); // 存取內部函式的變數
console.log(balance); //900

因為變數在函式內,無法重複取得,所以一次後就會釋放記憶體,也無法取用變數。

工廠模式

不要直接呼叫,而是讓函式賦予在另一個變數上,就會將 myMoney 變數存在內層的作用域,在每次執行後不斷更新此值。

1
2
3
4
5
6
7
8
9
10
11
12
function buyItem() {
var myMoney = 1000;
return function (price) {
// 這裡就是一個閉包,不過目前只會使用一次
myMoney = myMoney - price;
return myMoney;
};
}
let balance = buyItem(); // 存取內部函式的變數
console.log(balance(100)); //900
console.log(balance(200)); //700
console.log(balance(300)); //400
  • 不能使用 buyItem() 呼叫,因為執行結果會出現 function ... 的物件,沒辦法直接使用。
  • 透過 balance 變數,將 buyItem() 的值賦予給其變數,使其可以不斷的反覆呼叫,且內層記憶體不會被釋放。
  • balance 每次執行時,只會執行內層的函式,在內層記憶體沒有被釋放的情況下,myMoney 變數會不斷的被更新。
  • 透過給予預設值與固定流程,帶入參數後會得到值的執行過程,類似工廠一樣,又稱為工廠模式。

私有方法

別於工廠模式只有單一種方法,私有方法是將結果傳入到另一個物件內,物件內的屬性都是一段函式,在將要使用的方法寫入其內,並可在外部取用該方法得到想要的運算結果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function buyItem(initValue) {
var myMoney = initValue || 1000;
return {
increase: function (price) {
myMoney += price;
},
decrease: function (price) {
myMoney -= price;
},
value: function () {
return myMoney;
},
};
}
var balance = buyItem(100);
balance.increase(1000);
balance.decrease(500);
console.log(balance.value());

結語

要了解閉包,就要了解函式的作用域變數的作用域函式的運作原理,就不會被專有名詞搞得團團轉。

參考資料