iT邦幫忙

2021 iThome 鐵人賽

DAY 13
1
Modern Web

JavaScript學習日記系列 第 13

JavaScript學習日記 : Day13 - 閉包(Closure)

  • 分享至 

  • xImage
  •  

當一個函數被建立時,閉包就會被產生,雖然常見的閉包說明方式會使用巢狀函數當作例子,這是最常見的例子沒錯,但是並不是只有巢狀函數才能產生閉包。

直接舉一個例子:

function func() { // func1引用了它外層的變數a,因此func成為了閉包
    let a = 123
    function func1() {
        console.log(a) //訪問了外層的func內的a
        debugger;
    }
    func1();
}
func()

上圖可得知函數建立時就會存在閉包了,再進入call stack中的func1

進入func1後,可以發現closure進到了Scope,代表閉包也算是作用域的一種。

return function

直接舉一個例子說明:

function getIntro(height,weight) {
    function addString() {
        console.log(`身高${height},體重${weight}`)
    }
    return addString
}

let getIntroString = getIntro(180,70);
getIntroString();
  1. getIntro函數傳入兩個參數,這兩個參數作用域就在getIntro funciton中,如果沒有被存取或是參考的話就會從記憶體中釋放。
  2. 內層addString函數存取height與weight,該函數內找不到所以往上找到getIntro function內的。
  3. addString並不是馬上執行,而是當作getIntro function的返回值,賦值給getIntroString。
  4. 運行getIntroString,會運行內層的addString,並且存取height與weight,因為height與weight還是維持有被參考,所以並不會被記憶體釋放而回收,變成了getIntroString的私有變數。

另外返回的function是可以重複且獨立使用,閉包內的變數是互相獨立的,舉個例子:

function plusNum() {
    let initNum = 100;
    return function(num = 0) {
        initNum+=num
       console.log(`current num is ${initNum}`)
    }
}

let plusNumA = plusNum();
plusNumA(); // current num is 100
plusNumA(10); // current num is 110
plusNumA(20); // current num is 130

let plusNumB = plusNum();
plusNumB(); // current num is 100
plusNumB(20); // current num is 120
plusNumB(40); // current num is 160


上一篇
JavaScript學習日記 : Day12 - Event Loop
下一篇
JavaScript學習日記 : Day14 - 原型與繼承(一)
系列文
JavaScript學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言