iT邦幫忙

0

JS 閉包(Closure) DAY63

  • 分享至 

  • xImage
  •  

閉包(Closure)

可以讓資源的記憶體不被釋放,讓外部能重複執行

function storeMoney(){
    var money = 100;
    // 這裡子函式我們假設名稱 func
    return function(price){
        money = money + price;
        return money;
    }
}
// 因 func 的 money 會因範圍練而像外層尋找
// 所以 storeMoney() 的 money變數會保留,不會釋放記憶體
console.log(storeMoney()); // 子函式
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)
function storeMoney(){
    var money = 100;
    return function(price){
        money = money + price;
        return money;
    }
}
// 因 子函式 的 money 會因範圍練而像外層尋找
// 所以 storeMoney() 的 money變數會保留,不會釋放記憶體
console.log(storeMoney()); // 子函式
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)
console.log(storeMoney()(100)); // 200 (執行完就結束了,直接釋放記憶體)

// 為什麼可以一直累加??
// MingMoney變數 接收子函式結果,而子函式會一直取用父函式(storeMoney)的 money 
// 導致 storeMoney 函式裡第 2 行的 money 不斷地改變數字

// 而為什麼 storeMoney 函式裡第 2 行的 money 不會被記憶體釋放??
// MingMoney變數 會因範圍練而像外層尋找 , 所以"參照" storeMoney 函式裡第 2 行的 money 
// 故串連起來,外界跟外層 storeMoney 變的有關聯
var MingMoney = storeMoney(); 
console.log(MingMoney(1000)); // 1100
console.log(MingMoney(1000)); // 2100
console.log(MingMoney(1000)); // 3100

var JayMoney = storeMoney(); 
console.log(JayMoney(1000)); // 1100
console.log(JayMoney(1000)); // 2100
console.log(JayMoney(1000)); // 3100




工廠模式及私有方法

我們先來看一個例子


function arrFunction(){
    var arr = [];
    for(var i = 0 ; i < 3 ; i++){
        arr.push(function(){
            console.log(i); // 是取函式作用域的 i ,但這時 i 為 3 
        })
    }
    console.log('i' + i); // 3 
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

解決方法(2種)
利用 立即函式 限制作用域

function arrFunction(){
    var arr = [];
    for(var i = 0 ; i < 3 ; i++){
        (function(j){
            arr.push(function(){
                console.log(j); // 0 1 2
            })
        }(i))
    }
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

JS ES6 let

function arrFunction(){
    var arr = [];
    for(let i = 0 ; i < 3 ; i++){
        arr.push(function(){
            console.log(i); // 0 1 2
        })
    }
    return arr;
}
var fn = arrFunction();
fn[0]();
fn[1]();
fn[2]();

函式工廠

function storeMoney(init){
    var money = init || 100;
    return function(price){
        money = money + price;
        return money;
    }
}
var myMoney = storeMoney(100);
console.log(myMoney(500)); // 600

私有方法

function storeMoney(init){
    var money = init || 100;
    return {
        increase: function(price){
            money += price ;
        },
        decrease: function(price){
            money -= price;
        },
        value: function(){
            return money
        }
    }
}
var myMoney = storeMoney(500);
myMoney.increase(1000);
myMoney.increase(1000);
myMoney.increase(1000);
myMoney.decrease(500);
myMoney.decrease(500);
console.log(myMoney.value()); // 2500

那今天的介紹就到這裡
若有任何問題 或 內容有誤
都可以跟我說唷/images/emoticon/emoticon41.gif


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言