JS20min Day — 17 生活化閉包 (Clouser)

閉包(Closure)是指能使用獨立(自由)變數的函式(在使用運用,但在封閉的作用域中定義)。換言之,這些函式能「記得」被建立時的環境。

這個詞可能有點難理解,但我會盡量用比較「口語」的方式解釋什麼是閉包。

閉包(Closure)也是由一個函數所組成,但我可能會將閉包的這個工人,在說成更大的工廠,而這個工廠底下會有其他函數在做事情,而這些函數會照著這工廠已經預設的內容進行組裝或配置。

建立工廠

function factory(category) {
const factoryCategory = category
return function(name) {
alert('we make ' + factoryCategory + ' name: ' + name)
}
}

首先我們這次建立了一個工廠,而不是工人,這個工廠名稱就叫做 factory,這個工廠也有一個「()」可以丟入我們所要設定的預設值,而在這段程式中代表的就是我們要生產的「產品類別(category)」。

接下來設置一個「變數(factoryCategory)」來保留這個「產品類別(category)」的名稱。

最後我們會請一位「匿名函數」,也就是沒有名稱的工人來幫忙做事,可能就把它當作一個自動機器人,不需要名稱,就是做它該做的事情。

注意到程式中的 return 了嗎?這個 return 會將我們的「匿名工人」帶回給我們建立的「工廠變數」中,怎麼說呢?看看例子吧!

const carFactory = factory('car')

現在我們透過一個「變數(carFactory)」建立了一個工廠,這工廠負責的就是生產「車子(car)」。

接下來我們就可以開始生產一部部的車子了,來看看這「匿名工人」所做的事情

return function(name) {
alert('we make ' + factoryCategory + ' name: ' + name)
}

這個自動化工人,會透過工廠原本就定義好的 factoryCategory 分類,然後製造一台車子,並跳出提視窗出來,所以最後就會跳出「we make car name xxx」的結果。


那這樣有什麼好處呢?其實有幾個優點:

  1. 保持變數的環境不被污染(scope)
  2. 一個獨立個體的工廠,可以被重複利用而不互相影響

假如同時有兩個工廠時,我們可以運用閉包(Clouser)的方式來配置兩個不同的工廠,做個範例試試看:

function factory(category) {
let factoryCategory = category
return function(name) {
alert('we make ' + factoryCategory + ' name: ' + name)
}
}
let carFactory = factory('car')
carFactory('abc')
carFactory('cds')
let animalFactory = factory('animal')
animalFactory('cat')
animalFactory('dog')

上述例子中我們得到了兩個工廠,分別是「carFactory」跟「animalFactory」,輸出的結果就會是

  1. 「we make car name abc」
  2. 「we make car name cds」
  3. 「we make animal name cat」
  4. 「we make animal name dog」

參考資料

看看其他相關教學

Day — 1 基本結構 (The Structure of JavaScript), 物件 (Object)

Day — 2 變數 (Variable)

Day — 3 運算子 (Operator)

Day — 4 函數 (Function)

Day — 5 流程控制 (Flow Control)

Day — 6 視窗 (Window), 時間控制(Timer)

Day — 7 認識 HTML, 認識元件, 命名元素 (HTML)

Day — 8 事件 (Event)

Day — 9 選擇器 (Selector), 改變樣式 (Style)

Day — 10 Event 進階應用

Day — 11 CSS Style 與 JavaScript 的互動

Day — 12 龜兔賽跑

Day — 13 jQuery 引用與基本使用 (jQuery)

Day — 14 淡出與淡入 (fadeIn, fadeOut)

Day — 15 滑動效果 (SlideUp, SlideDown)

Day — 16 設置內容 (text, html) 登入流程範例

Day — 17 生活化閉包 (Clouser)