閉鎖について調べてみましょう!


MDNの定義



話がちょっと難しい…!解いて理解しよう!

LexicalScoFran?

  • JSエンジンは、関数がどこで呼び出されるかではなく、関数定義に基づいて位相スキャンを決定する.これはレイクシー・カルスコフと呼ばれています.
  • 正確には、レイクシー環境の「外部レイクシー環境(外部語彙範囲)への参照」に格納される参照値、すなわち、親スコフへの参照は、関数を定義し、評価時に存在する環境によって決定される.これはLexicallscopeです!
  • function init() {
      var name = "Mozilla"; 
      function displayName() { // displayName() 은 내부 함수이며, 클로저다.
    	console.log(name) //Mozilla
      }
      displayName();
    }
    init();
    上のコードでは、displayName関数にはnameという領域変数はありません.しかしinitを実行するとmozillaは良好な出力を得る.これは、displayName定義時に親スキャンが外部ディレクトリ環境リファレンスに格納されるためです.
    自分の地域変数はありませんnameではなく、大尉スコフというnameです.

    味わう

    function makeAdder(x) {
      var y = 1;
      return function(z) {
        y = 100;
        return x + y + z;
      };
    }
    
    var add5 = makeAdder(5);
    var add10 = makeAdder(10);
    console.log(add5(2));  // 107 (x:5 + y:100 + z:2)
    console.log(add10(2)); // 112 (x:10 + y:100 + z:2)
    add 5とadd 10は同じmakeAdderを使用しますが、異なるコンテキスト環境を使用するため、異なる結果が得られます.

    利用する

    var counter = (function() {
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        increment: function() {
          changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
      };
    })();
    
    console.log(counter.value()); // logs 0
    counter.increment();
    counter.increment();
    console.log(counter.value()); // logs 2
    counter.decrement();
    console.log(counter.value()); // logs 1
    counterはインスタント実行関数なのでcounterのprivateCounterにアクセスできません.ただし、親の変数privateCounterが外部のディレクトリ環境参照に格納されているため、内部関数changeByはアクセスできます.
    注-mdn