学習第6話毎週学習内容


エンクロージャ


Closerはjavascriptを習ってずっと聞いていた用語ですが、ずっと避けようと努力していました.ああ、知りたくないからです.

モジュールの定義


関数と宣言されたディレクトリ環境の組合せ
ということで.何を言ってるんだ?10回読み直すんだ今、それがどういう意味なのか調べてみましょう.
覚えていますか.jsエンジンは、どこで定義された関数に基づいて親スキャンを決定します.
const x = 1;
function foo(){
  const x = 10;
  bar();
}
function bar(){
  console.log(x);
}
foo(); // ? 뭘까
bar(); // ? 뭘까
実行コンテキストで見られるように、決定関数の親スキャンは、ディレクトリ環境외부 렉시컬 환경에に対する参照値を決定することに相当する.関数は、独自に定義した環境参照を内部スロット[Environment]に格納します.すなわち、実行中の実行コンテキストのディレクトリ環境への参照が格納される.上記のコードでは、foo、barの関数は、定義時にグローバルコレクション環境の参照を格納します.したがって、グローバルスキャンで見つかったxの値1が吐き出される.

さあ、だからクロゼは何を言いましたか。

const x = 1;
function outer(){
  let x = 10;
  const inner = function(){
    x = 20;
    console.log(x)
  }
  return inner
}
const innerFunction = outer();
console.log(innerFunction()); // 20
上のコードからouter関数は内部関数を吐き出し、ライフサイクルを終了します.すなわち、実行コンテキストスタックでポップアップされます.outer関数が死亡したため、関数の領域変数xもライフサイクルを終了する.つまり地域変数xを参照することはできないが...内層関数を呼び出し,終了と思ったxが戻ってきた.
ネストされた関数が外部関数よりも長く保持されている場合、ネストされた関数は、ライフサイクルが終了した外部関数の変数を参照できます.この重畳関数を閉鎖器と呼ぶ.

ねえ、この可能性のある原因は何ですか?


これは、外部関数のライフサイクルが終了しても、外部関数の実行コンテキストがスタックから除去され、外部関数の集合環境が消滅しないためです.ネストされた関数の[Environment]内部スロットは外部関数の集合環境を参照し、ネストされた関数はinnerFunctionによって参照されるため、仮想集合のターゲットにはなりません.

では、すべての重ね合わせ関数はCloserですか?


そうじゃない~
  • 位相ミラーの識別子を参照する関数であるべきである.モダンブラウザは頭がいいので、余分な参照のない識別子は覚えていません.
  • 位相鏡の識別子を参照しても、内部関数のライフサイクルは外部関数よりも長い.
  • 要約すると、モジュールは、ネスト関数が親スキャンの識別子を参照し、ネスト関数が外部関数よりも長く保持されている場合にのみ呼び出される.

    だから、Closer、どうやって利用すればいいのでしょうか。