iT邦幫忙

2021 iThome 鐵人賽

DAY 24
0
自我挑戰組

JavaScript 核心觀念系列 第 24

【Day24】閉包(Closure)

  • 分享至 

  • xImage
  •  

今天我要講解的是閉包(Closure),在進入之前我們先來看一段程式碼,

首先準備一個隨機生成字串的函式

function randomString(length) {
    let result = '';
    let characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    for (let i = 0; i < length; i++) {
        result += characters.charAt(Math.floor(Math.random() * characters.length));
    }
    return result;
};

接著在全域中新增一個變數和函式,並且執行該函式

let demoData = [];

function getData() {    
    for (let i = 0; i < 1000; i++) {
        demoData.push(randomString(1000))
    }
};

getData();

我們能看見這段程式碼佔記憶體空間 20.6 MB,

接著我們將變數移到函式內,再看一次佔多少記憶體空間

function getData() {    
    let demoData = [];
    for (let i = 0; i < 1000; i++) {
        demoData.push(randomString(1000))
    }
};

getData();

此時會看見程式碼佔記憶體空間 815 KB,

在此附上 KB 和 MB 的單位轉換: 1 MB = 1024 KB

那麼為何所佔的記憶體變少呢?

那是因為在函式中的變數所佔的記憶體,

在函式執行結束後,此時函式內的變數沒被參考,

所以該變數所儲存的記憶體空間就被釋放掉,

因此所佔的記憶體就變少了

而當函式內的變數記憶體還保留時,這就是所謂的閉包(Closure)

閉包(Closure)

當函式內的變數其值被保留,而不被記憶體釋放時,稱為閉包(Closure)

範例:

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

console.log(storeMoney);

console.log(storeMoney());

console.log(storeMoney()(100));

該範例中 storeMoney() 回傳匿名函式,而匿名函式中則回傳 money

在第一個 console.log() 中,會回傳 storeMoney() 整個函式,

在第二個 console.log() 中,會回傳匿名函式,

在第三個 console.log() 中,會回傳 1100

那為何會回傳 1100 呢?

那就跟它的作用域有關係了,

在匿名函式中因為沒有變數 money 所以向外查找該變數,

也因為向外查找這個動作,就讓 money 的值無法被釋放,

所以 money 的值必須保存起來,匿名函式中才能取用該變數做使用,

因此才會回傳 1100

接著我們將函式賦予到變數上

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

const wei = storeMoney();

console.log(wei(100));  // 1100
console.log(wei(100));  // 1200
console.log(wei(100));  // 1300

我們能看到回傳的結果會累加,

這是因為在 storeMoney() 中,

我們將 100 這個參數代入匿名函式進行相加,

而相加後的值也會保留起來不被釋放,

因此當我們不斷將參數帶入時, money 的值也會不斷累加,

還有因為我們是在函式中宣告變數,

因此這個範例中的 money 的值,只屬於 wei 這個變數

當我們再宣告其他變數時,其值是互不相關的

function storeMoney(){
    let money = 1000;
    return function(price) {
        money += price;
        return money
    }
};

const wei = storeMoney();

console.log(wei(100));  // 1100
console.log(wei(100));  // 1200
console.log(wei(100));  // 1300

const ming = storeMoney();

console.log(ming(1000));  // 2000
console.log(ming(1000));  // 3000
console.log(ming(1000));  // 4000

以上就是今天閉包的解說,我們明天見!!


上一篇
【Day23】參數
下一篇
【Day25】閉包進階:工廠模式及私有方法
系列文
JavaScript 核心觀念30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言