Javascript筆記:Closure(閉包)概念

Posted by Kubeguts on 2017-09-13

閉包(closure): 為一個function包在某一個函式內,用return來取得內部function的回傳值

Closure are commonly used to give objects data privacy.

為什麼要有閉包??

因為有以下問題
ㄧ、Counter dilemma

1
2
3
4
5
6
7
8
9
10
11
12

var counter = 0;

function add() {
counter += 1;
}

add();
add();
add();

// the counter is now equal to 3

counter被改變成3、不過也可以不用透過add()直接更改counter的值。
那這樣會造成變數污染衝突。

1
2
3
4
5
6
7
8
function add() {
var counter = 0;
counter += 1;
}

add();
add();
add();

counter被宣告在add()內,為local variable,不會被其他function或global改寫。
但會有重複呼叫add()後無法使counter值做累加的動作。
(因為var counter使變數重複被定義)。

二、解決方法

1
2
3
4
5
6
7

function add() {
var counter = 0;
function plus() {counter += 1;}
plus();
return counter;
}

透過內部plus函式才能更改counter值、解決counter dilemma問題,不過還會遇到var counter重複宣告的問題,這時候就得用閉包的技巧!如下:

1
2
3
4
5
6
7
8
9
10
11

var add = (function () {
var counter = 0;
return function () {return counter += 1;}
})();

add();
add();
add();

// the counter is now 3

將add變數宣告成 self-invoking function(僅執行內部一次 var counter不會在add()第二次被呼叫時再次被宣告),然後回傳function expression,如此一來add變數就變成 add() function了!

1
2
var counter = 0;
return function () ***{return counter += 1;***}

就被包在add()函式內,直接呼叫add() 就只會跑上面*的部分。

以上做法即為closure閉包,使得變數不會被污染和衝突。