閉包
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | function storeMoney() {var money = 500;
 return function (price) {
 money = money + price;
 return money
 }
 };
 var mingMoney = storeMoney();
 console.log(mingMoney(50)); // 550
 console.log(mingMoney(50)); // 600
 console.log(mingMoney(50)); // 650
 
 | 
這邊可以發現 mingMoney 的值有繼續被增加,原因是實際上釋放記憶體的條件是「當變數無法被引用時就會釋放記憶體」,而現在這個函式被綁定在全域變數上,所以它能夠不斷的呼叫,所以記憶體並不會被釋放。
再來看下一個範例
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 
 | function storeMoney() {var money = 500;
 return function (price) {
 money = money + price;
 return money
 }
 };
 var mingMoney = storeMoney();
 console.log(mingMoney(50)); // 550
 console.log(mingMoney(50)); // 600
 console.log(mingMoney(50)); // 650
 
 var jayMoney = storeMoney();
 console.log(jayMoney(1000)); // 1500
 console.log(jayMoney(1000)); // 2500
 console.log(jayMoney(1000)); // 3500
 
 | 
這裡兩個變數各自呼叫了函式,所以它們會有各自的回傳結果。
也可以想成每次回傳都生成一個新的位址。
閉包申論
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | function arrFunction(e) {var arr = [];
 for (var i = 0; i < 3; i++) {
 arr.push(function (e) {
 console.log(i);
 });
 }
 console.log('i = '+ i);
 return arr;
 }
 
 var fn = arrFunction();
 fn[0]();
 fn[1]();
 fn[2]();
 
 | 

會造成全部都出現 3 是因為 var 的作用域是在 function 內,所以它會汙染到 for 外面的 i 。
解決方法很簡單 ↓
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 
 | function arrFunction(e) {var arr = [];
 for (let i = 0; i < 3; i++) {
 arr.push(function (e) {
 console.log(i);
 });
 }
 //console.log('i = '+ i); // 如果有這層程式碼會報錯,因為找不到 i 變數
 return arr;
 }
 
 var fn = arrFunction();
 fn[0]();  // 0
 fn[1]();  // 1
 fn[2]();  // 2
 
 | 
因為 let 的作用域是限制在 {},所以在 for 就已經把它限制住了。
閉包工廠
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | function storeMoney(initValue) {var money = initValue || 500;
 return function (price) {
 money = money + price;
 return money
 }
 };
 
 var mingMoney = storeMoney(100); // 起始 100
 console.log(mingMoney(500));  // 增加 500
 
 | 
這裡利用了 var money = initValue || 500; 來做出預設值。
私有方法
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 | function storeMoney(initValue) {var money = initValue || 500;
 return {
 increase: function (price) {
 money += price;
 },
 decrease: function (price) {
 money -= price;
 },
 nowMoney: function (price) {
 return money;
 }
 };
 };
 
 var mingMoney = storeMoney(100); // 起始 100
 mingMoney.increase(100);    // 起始 100 + 100 = 200
 mingMoney.increase(100);    // 200 + 100 = 300
 mingMoney.decrease(50);    // 300 - 50 = 250
 mingMoney.decrease(25);    // 250 - 25 = 225
 console.log(mingMoney.nowMoney()); // 最後會顯示 225
 
 | 
這是可以在回傳的時候加入一個物件,利用物件去做加減的運算。