JS踩坑筆記 - closure


Posted by Nacho on 2020-09-21

Online JS 執行環境(nodejs)
https://repl.it/languages/nodejs

關於 closure 的幾個重點:

從範例程式理解closure:

  • funcInside 是一個 closure
  • funcInside只能給func使用
  • funcInside有一個自己的變數b及一個不是自己的變數a
  • 但它可以往上層去找,只要它找得到,於是發現a=10
  • 因為回傳是funcInside的結果,所以這個func實際上是funcInside函式
  • 只是透過func將它包裝起來了 => 這招叫封裝
function func() {
  var a = 10;
  function funcInside(b) {
    console.log("a+b=", a + b);
  }
  return funcInside;
}

var newFunc = func(); //接收的是 funcInside 函式
newFunc(5) // a+b=15

所以...closure是什麼?

  • 是函式以及該函式被宣告時所在的作用域環境(lexical environment)的組合。
  • 白話來說,到底是什麼被關起來了,這就跟作用域環境有關了
  • 從上個程式的例子來看,因為funcInside用到不是自己參數的a,所以a就被JS給記錄下來了,即便func執行結束了,a的記憶體空間也不會被釋放!

closure與作用域環境:

  • makeAdder一個函式工廠:用來建立參數、並計算其參數和的function
  • add5與add10是兩個不同的closure,也就是說add5與add10有兩個不同的作用域環境
function makeAdder(x) {
  return function(y) {
    return x + y;
  };
}

var add5 = makeAdder(5); // 在作用域環境中,x=5
var add10 = makeAdder(10); // 在作用域環境中,x=10

console.log(add5(2));  // 7
console.log(add10(2)); // 12
  • closure與資料封裝的例子
var account = (function {
  var balance = 1000;
  return {
    deposit: function(d) {
      balance += d;
    },
    withdraw: function(w) {
      balance -= w
    },
    value: function() {
      return balance;
    }
  }
})();
account.value(); // 顯示 1000 餘額
account.deposit(500); // 實際餘額變 1500
account.withdraw(1000) ;// 實際餘額變 500
account.value(); // 顯示 500 餘額
account = null; // 解除引用

未完

覺得closure真的是一個有點複雜的概念!
加上又有性能上的考量,會用的機會應該很少,但還是要有基礎知識,才能辨識錯誤!
等未來有什麼新的心得會再補充上來
待讀...
https://pjchender.blogspot.com/2017/05/javascript-closure.html

參考

學習筆記參考:Javascript精選16堂課:網頁程式設計實作
https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Closures


#closure #javascript







Related Posts

Day05 LINE 2.0

Day05 LINE 2.0

MTR04_0814

MTR04_0814

[Day 07] - Vault 的進修之路

[Day 07] - Vault 的進修之路


Comments