Core JavaScript-02.実行コンテキスト


1朕運行コンテキスト


まずスタックとキューについて説明します.
📌 スタック(stack):入口が1つしかない井戸と同じデータ構造.
abcd順に進み,取り出し時はd,c,b,aの順であった.
📌 キュー(queue):1つの構造は入力のみを担当し、もう1つの構造は出力のみを担当します.abcd順に格納すると、ポップアップはabcd順になります.
📌 ≪実行コンテキスト|Run Context|emdw≫:実行コードに指定する環境情報を含むオブジェクト.
📌 実行コンテキストを構成する方法は次のとおりです.
1)グローバルスペース
2)eval()関数
3)関数
自動的に生成されるグローバル空間と悪魔と見なされるevalに加えて、通常、実行コンテキストを構築する方法は、関数を実行することである.

💻 実行コンテキストの順序をコードで理解しましょう

let a = 1;  ----------------- (1)
function outer() {
	function inner() {
    	console.log(a); // undefined
        let a = 3;
    }
    inner(); ----------------- (3)
    console.log(a); // 1
}

outer();   ----------------- (2)
console.log(a); // 1
📝 JavaScriptコードを初めて実行する場合
(1)グローバルコンテキストがcallスタックに含まれる.
ブラウザで自動的に実行されるため、JavaScriptファイルを開くとグローバルコンテキストがアクティブになることが理解できます.
(2)グローバルコンテキストに関連するコード順に操作しouter関数を呼び出す.
jsエンジンは外部の環境情報を収集し、外部実行コンテキストを生成し、callスタックに格納する.グローバルコンテキスト関連コードは一時停止します.
(3)外部内部で内部関数の実行コンテキストが再び呼び出しスタックの一番上にある場合は,外部コンテキストに関連するコードの実行を停止し,内部関数のコードを順番に実行する.
内部実行コンテキストが終了すると、呼び出しスタックから削除されます.
outerコンテキストは次に実行されます.同様にouter実行が終了すると、グローバルコンテキストが実行されます.終了すると、呼び出しスタックは何も残っていない状態で終了します.

実行コンテキストが有効になっている場合、jsエンジンはコンテキストに関連するコードに必要な環境情報を収集して格納します。これらのオブジェクトは何ですか?


これらのオブジェクトはjsエンジンの使用のために生成され、開発者はコードで検証できません.
含まれる情報は以下の通りです.
📌 VariableEnvironment:現在のコンテキスト内の識別子の情報+外部環境情報、および宣言時のLexicalEnvironmentのスナップショット
📌 LexicalEnvironment:最初はvariableEnvironmentと同じですが、変更はリアルタイムで反映されます.
📌 ThisBinding:この識別子は表示するオブジェクトです.

2️⃣ variableEnvironment


含まれる内容はLexicalEnvironmentと同じですが、初期実行時のスナップショットが保持されている点が異なります.
変化環境、メキシコ環境の内部は環境記録と外部環境から構成されている.

3️⃣ LexicalEnvironment


コンテキストを構成する環境情報を予め接触した感覚で収集する.

4πυ環境記録と護衛


EnvironmentRecordは、現在のコンテキストに関連するコードの識別子情報を格納します.
パラメータ識別子、宣言された関数がある場合、関数自体、varとして宣言された変数の識別子などの識別子に対応します.
コンテキスト全体を最初から最後まで順番に収集します.
コードはアクチュエータの前任者であるにもかかわらず、jsエンジンはこの環境内のすべてのコードの変数名を知っている.
jsエンジンは識別子を最上位に引き出し、実際のコードを実行します.
ここからハウスティンの概念を引き出す.

メッシュルール


EnvironmentRecordには、パラメータ名、関数宣言、変数名が含まれます.
function a(x) {
	console.log(x); // undefined
    var x;
    console.log(x); // undefined
    var x = 2;
    console.log(x); // 2
}

a(1);
ハイライトされていない場合、出力値は以下のようになります.

jsエンジンの駆動方式を人間の観点から理解し、コードを変えましょう。


△実際のエンジンはこのような転換過程を経ずに、誤解しないでください。

function a(x) {
	var x = 1; // 수집 대상 1(매개변수 선언)
	console.log(x);
    var x; // 수집 대상 2 (변수 선언)
    console.log(x); 
    var x = 2; // 수집 대상 3 (변수 선언)
    console.log(x); 
}

a(1);
パラメータを変換するときは、変数の宣言/割り当てとみなされます.
function a(x) {
	var x; // 수집 대상 1 (매개변수 선언)
    var x; // 수집 대상 2 (변수 선언)
    var x; // 수집 대상 3 (변수 선언)
    
    x = 1; // 수집 대상 1의 할당
	console.log(x); // 1
    
    console.log(x); // 1
    x = 2;  // 수집 대상 3의 할당
    console.log(x);  // 2
}

a(1);
出力結果は1、1、2です.
関数宣言の例について
function a() {
	console.log(b); // undefined
    var b = 'bbb';
    console.log(b);  // 'bbb'
    function b() {}
    console.log(b); // 'bbb'
}
予想通り、いったい?
function a() {
	var b;
    var b = function b() {} // 호이스팅이 끝난상태에 함수선언문은 변수에 할당한것 처럼
    
	console.log(b); // function b
    b = 'bbb';
    console.log(b);  // 'bbb'
    
    console.log(b); // 'bbb'
}
a関数を実行すると、a関数の実行コンテキストが作成されます.
変数名と関数宣言の情報を上に移動します.
変数は宣言と割当てに分けられ、宣言のみをドラッグ&ドロップします.
関数宣言は、関数全体を昇格させます.
呼び出し終了時の関数式は、関数名として宣言された変数に関数が割り当てられていると考えられます.

💡 var、const、letブート


var、const、letについて

💣 const,letはhoistingとも呼ばれ,実際には参照エラーが発生する.
理由は何ですか.

javascriptでは、変数は、宣言、初期化、割り当ての3つのステップで生成されます.
宣言:変数を実行コンテキストの変数オブジェクトに登録します.
≪初期化|Initialization|emdw≫:変数のメモリを作成するプロセスで、割り当てられたメモリを未定義に初期化します.
≪割当て|Assign|oraolap≫:定義されていない変数に異なる値を割り当てます.
varは宣言と初期化を同時に発生しますが、const/letは宣言と初期化が別々に行われ、メモリが割り当てられていないため参照エラーが発生します.
💣 TDZ領域(つまり死角領域)にメモリが割り当てられていないため、参照エラー

5ππ関数宣言文と関数式


📌 関数宣言
関数定義子のみが存在し、個別の割り当てコマンドがない関数名を定義する必要があります.
function a() {}
📌 関数式
定義した関数を別の変数に割り当てます.
関数名を定義する関数は記名関数式、定義しない関数は匿名関数式です.
一般的には匿名関数式を指します.
let b = function() {} // 익명함수 표현식

let c = function d() {} // 기명함수 표현식
9200過去には、デバッグ時の匿名関数式の関数名がundefined、unnamedであるため、シンボル関数式がよく使用されていました.
ただし、匿名関数式の変数名は、すべてのブラウザで関数のname propertyに割り当てられます.必ずしも記名関数を使用する必要はありません.

💻 関数宣言、式エスケープ


📌 関数宣言式はjsロード時に変数オブジェクトに関数を割り当て、変数オブジェクトにコードを格納しすぎるとアプリケーションの応答速度が遅くなる可能性があります.
ただし、関数式は実行時に実行されるので、関数式を使用することをお勧めします.
console.log(sum(1,2));
console.log(multiply(3,4));

function sum(a,b) {
	return a + b;
}

var multiply = function (a,b) {
	return a * b;
}
このようなコードがあります.
選択されると、以下のようになります.
function sum(a,b) { // 함수 선언문은 전체를 호이스팅
	return a + b;
}

var multiply; // 변수는 선언부만 끌어올림


console.log(sum(1,2));
console.log(multiply(3,4));


multiply = function (a,b) { // 변수 할당부는 원래 자리에
	return a * b;
}

関数をグローバルスペースで宣言したり、同じ名前の関数を繰り返し宣言したりしない限り、関数式として定義すると、境界効果を低減できます。



📌 スキャン
識別子の有効範囲.
スキャンは、グローバルスペース以外の関数でのみ生成されます.
📌 スキャンチェーン
これは、識別子の有効範囲を内から外へ順次検索することを意味する.
可能にしたのは辞書環境の2番目の収集資料outerEnvironmentReferenceです.
たとえば、A関数でB関数を宣言し、B関数でC関数を再度宣言します.
関数Cの外部環境は、関数BのLexicalEnvironmentを参照する.
関数BのLexicalEnvironmentのouterEnvironmentReferenceはsms AのLexicalEnvironmentを参照します.
同様に、outerEnvironmentReferenceは接続リスト形式を呈する.
宣言時のLexicalEnvironmentのみを参照するため、最近の要素から順にアクセスできますが、他の順序でアクセスすることはできません.
無条件は、スキャンチェーンで最初に発見された識別子にのみ近づくことができます.

📚 整理する


📌 ≪実行コンテキスト|Run Context|emdw≫:実行コードに指定する環境情報を含むオブジェクト.
グローバル空間で自動的に生成されるグローバルコンテキストと、evalと関数によって生成されるコンテキストが含まれます.
📌 実行コンテキストオブジェクトがアクティブな場合、VariableEnvironment、LexicalEnvironment、ThisBindingの3つの情報が収集されます.
📌 実行コンテキストを作成すると、VariableEnvironmentとLexicalEnvironmentは同じ内容で構成されますが、LexicalEnvironmentは関数の実行中に発生した変更をすぐに反映します.
VariableEnvironmentは初期状態のままです.
📌 VariableEnvironment、LexicalEnvironmentは、パラメータ名、変数の識別子、宣言関数の関数名などを収集する環境記録と、前のコンテキストを参照するLexicalEnvironmentReferenceからなる.
📌 Hoistingは、環境記録収集プロセスを抽象化した概念であり、環境記録の収集プロセスを実行コンテキストが関与するコードセットの最上位に昇格させ、コードをより簡単に説明する.
宣言子のみが呼び出され、割り当てプロセスは元の場所に保持されます.これにより、関数宣言文と関数式の違いが発生します.
📌 スケールは変数の有効範囲を表します.
outerEnvironmentReferenceは、この関数が宣言する場所のLexicalEnvironmentを参照します.コード内の変数にアクセスしようとする場合は、現在のコンテキストのLexicalEnvironmentで値をナビゲートし、見つからない場合は外部EnvironmentRecordでLexicalEnvironmentをナビゲートします.
グローバルテストのLexicalEnvironmentを検索しても、変数が見つからない場合はundefinedを返します.
📌 グローバル変数:グローバルコンテキストのLexicalEnvironmentに含まれる変数.
📌 領域変数:関数によって生成される実行コンテキストの変数.