iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0
Modern Web

[學習筆記] 邊學邊寫 JavaScript 30天系列 第 25

[學習筆記] 邊學邊寫 JavaScript 30天 (25):Closure

  • 分享至 

  • xImage
  •  

前言

今天研究的項目是Closure閉包,理解這個之前要先理解這兩天的筆記 Hoisting

今天內容

  • Closure
  • IIFE

筆記

  • Closure
    先來一個情境比較好理解:假如今天我的銀行帳戶有99元,設定每次最多只能領10元。

    var money = 99
    function add(num) {
      money =  money + num
    }
    function reduce(num) {
      if (num >= 10) {
        money = money - 10
      } else {
        money = money - num
      }
    }
    add(1)
    reduce(100)
    console.log(money)  //90
    //這樣的設計看起來沒錯,但...我的money這個變數卻是可以被隨意修改的。
    money = 200
    console.log(money)  //200
    

    要多少自己改啊,直接實現財富自由。
    變數放的位置在global不管是誰都拿得到也改得到。
    改用function來包住money

    function account(initMoney) {
      var money = initMoney
      return {
        add: function(num) {
          money =  money + num
        },
        reduce: function(num) {
          if (num >= 10) {    // 超過 10 塊只扣 10 塊
            money = money - 10
          } else {
            money = money - num
          }
        },
        getMoney() {
          return money
        }
      }
    }
    
    var money = 200   //直接更改就改不到裡面的money了
    
    var account = account(99)
    account.add(1)
    account.reduce(100)   // reduce:超過 10 塊只扣 10 塊
    console.log(account.getMoney())  //90
    

    先從目的層面來看:從這個情境可以知道為什麼需要Closure,可以讓變數不會在Global被污染。就算Global也有一個money,但卻不會跑到我的帳戶裡QQ醒醒吧,你還是只有90元。

    再來從原理層面來看是怎麼運作的?
    在昨天講到執行環境,照理說當一個function執行完了,應該就不見了。
    為什麼經過return(一個move又回來了?)而且外面還拿得到裡面的值。
    原因在於只要被外面return後,就會有一個看不見的連結在,使得存有這個變數的function不會被消失。可以看成Activation Object都還在可以被父作用域給存取。將變數封裝在function account(initMoney)裡面。

    這邊先更正一下昨天說的進到 Global Execution Context 會產生Variable Object,但在進到 function Execution Context 則會產生 Activation Object。
    差別在於Activation Object裡面會有一個arguments,但兩者其實是做一樣的事,可以先把Activation Object(AO)當成Variable Object(VO)。

  • IIFE 立即呼叫函式
    很多說到Closure都會一起講這個,這個立即呼叫的作用跟名字一樣立即呼叫執行, 用完就丟? 常用於匿名函式。
    從結果可以理解使用在匿名函式的原因。都匿名了要怎麼呼叫?
    語法:第一個括號包住匿名函式,(括號也是優先執行)。
    後面再一組()是function呼叫用法,有沒有匿名都需要呼叫。
    (function{...執行內容...})()


參考資料


上一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (24):Hoisting II
下一篇
[學習筆記] 邊學邊寫 JavaScript 30天 (26):prototype I
系列文
[學習筆記] 邊學邊寫 JavaScript 30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言