Closure 閉包

這是 JavaScript 中一個很有趣的特徵,它作用在函式的閒置變數與當時環境綁定。

所以建立函式不等於 Closure。是將外部變數使之繼續存活或關入自己的範疇中才稱之為 Closure。

如下:

var wrapper = function () {
  var x = 100;
  function inner(val) {
     return x + val;
  }
  return inner;
}();

console.log(wrapper(2));

變數 x 沒有定義在 inner 內中,實際上 x 是從外部函式來的,函式 inner 建立了 Closure,

把 x 關入了自己的範圍中讓它繼續存活延續了 x 的生命週期。

要注意的是 Closure 關閉的是變數,而不是值

var wrapper = function () {
  var x = 100;
  function inner(val) {
    x = x + val;
    return x;
  }
  return inner;
}();

console.log(wrapper(2));  // 102
console.log(wrapper(60));  // 162

可以利用 Closure 的特性做出區域變數的區隔

function wrapper() {
  var x = 100;
  function inner(val) {
    x = x + val;
    return x;
  }
  return inner;
};

var layout_1 = wrapper();
var layout_2 = wrapper();

console.log(layout_1(2));  // 102
console.log(layout_2(60));  // 160

歸納

  • 特性

    • 在特定函式存取另一個函式的變數
    • 外層函式宣告的變數可以在內層函式取得
    • 作用域鏈結 (Scope Chain)
  • 閉包程式碼外觀

    • 運用在巢狀函式的定義

以下輸出結果又是如何呢 ?

var _array = [100, 200, 300, 400, 500];
function List() {
    var result = [];
    var i = 0;
    var length = _array.length;
    for (i=0; i<length; i++) {
        result[i] = function() {
            console.log(_array[i]);
        };
    }

    return result;
}

var price = List();
price[0]();    // ?
price[1]();    // ?
price[2]();    // ?
price[3]();    // ?
price[4]();    // ?

這是一個區塊範疇的陷阱,也會在實務應用中遇到。對不懂 closure 特性的開發人員會是一個很大的災難。

results matching ""

    No results matching ""