JS実行コンテキスト:scope、hill、closureの原理を理解しましょう


前述したようにjavascriptの動作原理を理解し,javascript v 8エンジンのcallスタックとメモリhipを学習した.
このとき,原理を簡単に理解するために「呼び出しスタックに実行関数を含める」と簡略化したが,実際には「実行コンテキスト」(Execution Context)である.
(ex.コード実行時はグローバル実行コンテキスト、関数A実行時は関数Aの実行コンテキスト、関数B実行時は関数Bの実行コンテキスト、以下に示す!)

📌 コンテキストを実行しますか?


コードを実行するために必要な環境を提供するオブジェクト

V.EとL.Eには環境記録とouterがあり、V.Eはコンテキストの初期実行ポイントのスナップショットを保持しますが、L.Eは変更を反映します.
このときアクティブ化される実行コンテキスト(Running execution context)は、呼び出しスタックを見たときに最初に見た=一番上のスタックフレームワークであると考えられる.

3種類のEC

  • グローバル実行コンテキスト
  • 機能実行コンテキスト
  • Eval機能実行コンテキスト
  • 📌 レコードでJS護送を理解する


    変数の作成原理


    シースについて議論する前に、変数の生成過程を見てみたいと思います.
    JavaScriptでは、変数の作成と定義は3つの段階に分かれています.
    1.宣言フェーズ(Declarationフェーズ):実行コンテキストの変数オブジェクトに変数を登録します.
    2.初期化フェーズ(Initializationフェーズ):メモリに変数オブジェクト(Variable Object)に登録されている変数があることを確認します.この段階では、変数はundefinedに初期化されます.
    3.アサイメントフェーズ(Assignmentフェーズ):未定義の初期化変数に実績値を割り当てます.

    がんばって


    変数宣言は最上位に引き上げられたようです.
    これは,JavaScriptエンジンがまずコード全体をスキャンし,変数などの情報を実行コンテキストの環境記録に格納し,物理的に最上位にドラッグするのではなく,実行コンテキストの環境記録に格納するためである.

    変数のシースと関数のシース


    へんすうかそく

    console.log(hi); //undefined 출력
    var hi="hello";
    console.log(hi); // hello 출력
  • var:varと宣言された場合、hi値はグローバルコンテキストの環境レコードで宣言され、未定義に初期化されます.{ hi : undefined }
  • let or const:コールスタックのグローバルコンテキストに宣言された環境レコードですが、初期化されません.したがって、宣言前に呼び出すとreferenceエラーが発生します.(仮死角)
  • 関数の加速

  • 変数で関数を矢印関数として使用する場合、関数式
  • hi();
    
    var hi=()=>{
    	//do hi 
    }
    グローバルコンテキストでは、環境レコードは{hi:undefined}で宣言および初期化されます.未定義を呼び出すことができないため、タイプエラー{hi:未定義}が発生します.
    hi();
    
    const hi=()=>{
    	//do hi 
    }
    変数ジャケットのlet、constと同じです.リファレンスエラーが発生しました
  • 関数キーワードを使用する場合、関数宣言
  • hi();
    function hi(){
    	//do hi
    }
    関数をキーワードとして宣言すると、宣言と同時に環境レコードにresearch:f()などの完了した関数オブジェクトが記録されます.つまり、間違いなく動作しています.この場合、宣言がなくても関数を使うことができるので、避けたいという人もいます.{ hi : f() }

    📌 Outerを使用してJSスキャンを理解する


    Outer Environment Reference:外部語彙環境を指します.
    let lamp=fasle;
    
    function goTo2F(){
    	let lamp=true;
        
        function goTo3F(){
        	let pet='puppy';
            console.log(pet);//puppy
            console.log(lamp);//true
            console.log(brie);//reference error
        }
        
        goTo3F();
    }
    
    goTo2F();
    この場合、JavaScriptエンジンはlampの値を考慮します.このように変数や関数を決定する値を「決定識別子」と呼ぶ.
    outerは、n−1層スタックフレームとn層スタックフレームを接続するはしごとして容易に抽象化することができる.
    上記のコードの形式であれば、
    レイヤ3はGoTo 3 Fの関数コンテキストです
    レイヤ2はgoto 2 fの関数コンテキストです
    階層1はグローバルコンテキスト
    つまり、有利な位置を占める3階建ての家屋の構造と似ている.
  • console.log(pet)を実行し、goTo 3 Fの関数コンテキストのレコードでpetの値を検索して出力します.
  • console.log(lamp)を実行すると、
    (1)goTo 3 Fの関数コンテキストのレコードでlamp-なしを検索する
    (2)外梯子に登って2階に降り、goto 2 Fでlamp-有を探し、その値を印刷し、閲覧を停止する.
  • console.log(brie)を実行すると、
    (1)goTo 3 Fの関数コンテキストのレコードでlamp-なしを検索する
    (2)外梯子に沿って2階に降りてGOTO 2 FでLAMPを探す-いいえ
    (3)グローバルコンテキストを検索する-ないため、参照エラーが放出されます.
  • 同じ識別子から2つのlampを出力するコードを実行すると、親スキャンで宣言された識別子の値が「変数シャドウ」と呼ばれるようにマスクされます.また,このように勾配(outer)によって変数を探索し探索するプロセス自体を「走査」と呼ぶ.

    📌 thisBinding


    ...今は理解できません.本を読みながら、この部分を書き直すつもりです.