JSキャビネット


実行コンテキストを学習した場合は、モジュールとは何かを知ることができます.

Closure


露出とは


MDNのモジュールに関するWebドキュメントでは、Closerについてこのように話しています.
Closerは、関数と関数が宣言する語彙環境の組合せです.モジュールを理解するには、まずJavaScriptが変数の有効範囲をどのように指定するかを理解する必要があります.
LexicalScopingとは?彼については以前に知っていた人です.関数が宣言された場所に基づいて関数を決定するスキャンをLexicalScopingと呼ぶ.
ここでいう語彙環境とはメキシコ環境を指す.実行コンテキストで遭遇するのは語彙環境です.これは翻訳の違いです.
用語はすべて知っているが、説明だけで分かるのは難しい.百聞は一見にしかず、百犬は一見にしかず.コードを作成し、理解します.
function outerFunc() {
     var a = 5;
     function innerFunc() {
     	console.log(a);
     }
     return innerFunc;
}

var inner = outerFunc();
inner(); //5;

通常、関数の内部に存在する変数は、関数の実行中にのみ存在します.しかしJSのモジュールは違います.
outerFunc関数を実行すると、内部宣言のinnerFunc関数が返されます.返されるinnerFunc関数は内部変数に含まれます.
内蔵のinnerFunc関数を実行するときに何が起こるかを説明しましょう.
innerFunc関数を呼び出すと、innerFunc関数の実行コンテキストが生成され、実行スタックにスタックされます.実行コンテキストには集合環境コンポーネントがあり、集合環境コンポーネントには環境レコード、外部環境参照、this bindingがあります.次にinnerFunc関数を評価します.
評価中にaという識別子が見つかります!では、JSエンジンはinnerFuncの環境記録でaという変数にナビゲートします.innerFuncにはaの識別子として宣言された割当て文がないため、innerFuncの環境レコードには変数はありません.a変数が見つからないJSエンジンはinnerFuncで外部環境参照をナビゲートします.innerFuncの外部環境参照はouterFuncの集合環境コンポーネントである.
innerFuncの外部環境参照として、近いOuterFuncの環境レコードでaという識別子にナビゲートします.ああ!ここにいたのか.JSエンジンは、この変数aをinnerFuncの「Scopes」という類似配列propertyの0番目のインデックスに格納します.元の0番目のインデックスはスペースを削除されます.
これでinnerFuncの評価は終了します.
では、innerFunc関数のコードを実行します.console.log(a)運転.自分のScopeを探索したが、aはなかった.[Scopes]を順番にブラウズします.Scopes[0]を参照...ああ!こちらです.aはkeyのvalue 5を表す.
ついにコンソールのロゴ5が現れました.

実際のコンソール.dir(内部)を試みると、アクセスする外部関数の変数への参照が自分の[Scopes]にClosureとして格納されます.
また、内部関数は、アクセスする必要のない外部関数の変数を参照しません.

コードではouterFuncに変数bがありますが、innerFuncのouterFuncでは変数bは存在しません.自分が参照する必要がある変数aのみが存在する.
innerFunc関数の評価段階ではこのように定められているからです.
「ここで気になりました」「では、三重ネスト関数のモジュールをどのように構成しますか?」

トリプルオーバーラップ関数の閉じる

function outerFunc() {
     var a = 5;
     function innerFunc() {
     	var b = 6;
        function innerinnerFunc() { console.log(b + a); };
        return innerinnerFunc;
     }
     return innerFunc;
}

var inner = outerFunc();
var innerinner = inner();

innerinner();
console.dir(innerinner);
outerFuncはinnerFuncを返します.innerFuncはinnerFuncを返します.innerFuncは、innerFuncの変数aとinnerFuncの変数bに近づいている三重オーバーラップ関数です.

ははは、コンソールログに11が表示されているのを見て、動作がいいです.console.dirを試してみよう
[Scopes]では、外部Funcモジュールと内部Funcモジュールが順番にスタックされていることがわかります.
ここから分かるのは何ですか.またJSエンジンを頭の中に回しましょう.JSエンジンです...
前の部分を省略してinnerFunc関数を呼び出す部分.
innernerFunc関数の実行コンテキストが作成され,関数のコードが計算される.識別子bに遭遇する.現在の実行コンテキストの環境レコードにはbはありません.外部環境参照としてinnerFuncの環境レコードを参照します.こちらです.関数実行コンテキストで見つかった関数の名前はinnerFuncで、実行コンテキストの所有者であるClosureです.このシール内にbを入れます.
この実行コンテキストは、グローバル実行コンテキストの2つのセルから離れています.InnernFuncの[Scopes]には2格子よりも遠い閉鎖領域が存在しますか?いいえ.
元のScopesを1つずつ押し開き、InnerFuncのScopes[0]を再作成し、ここにInnerFuncのCloseを挿入します.
次に識別子aに遭遇する.現在の実行コンテキストの環境レコードでaにナビゲートしますが、ありません.外部環境参照としてinnerFuncの環境レコードを参照します.ここにもありません.InnerFuncの外部環境参照としてOuterFuncの環境レコードを参照します.こちらです.関数セット環境コンポーネントで見つかった関数の名前はouterFuncです.この関数はClosureであり、この実行コンテキストの所有者です.このシールにaを加える.
この実行コンテキストは、グローバル実行コンテキストから1グリッドしか離れていません.InnerFuncの[Scopes]に1格子よりも離れた閉鎖領域は存在しますか?あります!innerFuncのクローズは、グローバル実行コンテキストよりも遠く、Scopes[0]に存在します.
Scopes[0]とインデックス値が小さいか同じScopes以外のScopesを1つ前に押し出し、Scopes[0]のindex+1 Scopesを作成した[1].次にScopes[1]にOuterFuncのClosureを加えます.
これでinnerFuncの関数評価が終了し、関数のコードが実行されます.Scope Chainで変数bとaが見つかり、コードはエラーを返さずに安全に終了します.
多分この感覚がコードに作用していると思います.実はifゲートとArrayspliceメソッドを使用してScopesが作成されます.

Closureにはディレクトリ環境があります。


次のコードを見てください.
function makeAdder() {
  var y = 1;
  return function(z) {
    return y + z;
  };
}

var add1 = makeAdder();
var add2 = makeAdder();

console.log(add1(3)); //4
console.log(add2(5)); //6

add 1およびadd 2は、closerとしてmakeAdder関数の変数yを参照する同じ関数によって生成される関数である.ただし、参照中のyの値は共有されない.
これは、関数評価フェーズでmakeAdder環境レコードの変数yをモジュールに読み込んでインポートする場合、変数yのメモリアドレスをコピーするのではなく、変数yとその値を完全にコピーして他のメモリに割り当てることを意味します.
すなわち,浅い複製ではなく,深い複製を行った.
これは、モジュールを作成するたびに、メモリのどこかにモジュールがあり、モジュールをむやみに作成するとメモリ漏れが発生することを意味します.
これの詳しい原理については、ゴミ収集器を学んだらわかります.

の最後の部分


以前、クロゼとスコフに位置づけたことがありますが、この文章はその高級版と言えるでしょう.以前の位置づけは「これはそうです.「私たちは後で原理を理解します.」こんな感じで今回の位置づけは『この動作はこうです』「原理はこうです」こんな感じ.
Closerを知っている以上、自然にゴミ収集器の概念につながっているのは不思議です.

コメントサイト


MDNのモジュールに関するWebドキュメント