Executeコンテキストベース


Execute context


まず、JavaScriptは変数を呼び出すとScopeという名前の場所にあります.
💡 Scopeとは?
  • Scope means area, space, or region.
    変数の有効範囲を表す用語
  • Global scope means global space or a public space.
  • Local scope means a local region or a restricted region.
  •  function fn1() {
        n1 = "n1"; //1번 코드
        var v1 = "v1"; //2번 코드
        let l1 = "l1"; //3번 코드
        const c1 = "c1"; //4번 코드
        fn2();
      }
      fn1();
    上のコードをデバッグして行ごとに実行しましょう.
    fn 1関数に入ると、Execute contextは次の図のようにCallStackという場所に積み上げられます.
    一つの比喩で説明すれば、Call Stackをフォルダと呼び、Scopeをファイルと呼ぶことができます.fn 1フォルダからアクセスできるファイルがfn 1のScopeです.したがって、最初に生成されたExecute context anonymousは、グローバルアクセス可能なExecute contextであるため、グローバルExecute contextとも呼ばれる.すなわち、プライマリコードでは、global executeコンテキストで宣言され、関数の外で宣言されます.
    これはExecute ContextがCall Stackの一部であることを示している.

    (1枚目写真:fn 1以外のコードでアクセス可能なScopeリスト)
    (2枚目の写真:fn 1関数でアクセス可能なScopeリスト)
    また、global execute contextの範囲内で変数を宣言する場合.
    varまたは何も貼り付けない場合は、Global scopeに変数として格納されます.
    letは、constと宣言された場合、Script scopeに格納されます.
    アラーム(1)とウィンドウ.コンソールウィンドウでalert(1)を実行したらどうなりますか?
    結果は同じです.ウィンドウオブジェクトはグローバルオブジェクトと同じです.したがってalertはグローバル役割ドメイン(windowオブジェクト)で指定されるので、windowオブジェクトと呼ばれても同じ値です.
    逆にletとconstとして宣言された変数はScript scopeに格納されます.したがって、ウィンドウ(global scope)オブジェクトから呼び出すことはできません.
    上図のfn 1 execute context内に入ってScopeを見ると、Localという名前のScopeが追加されていることがわかります.次に、fn 1関数で1番コードを実行するとglobal scopeでn 1が宣言されます.
    今回は2番コードを実行してみましょう.Local Scopeがv 1を生成していることがわかります.
    その後、コンソールでv 1、v 0を実行すると、結果値が得られます.v 1はfn 1 ExecuteコンテキストのLocal Scopeで見つかり、v 0はLocal Scopeで見つかり、Script Scopeで見つかりました.
    これらのScopeが一緒に接続されていることをScope Chainと呼ぶ.
    最後に、3番と4番のコードは実行時にLocal Scopeに指定されます.
    💡 GlobalとScript Scopeの違いは何ですか?
    Windowsオブジェクトの環境変数(古いスタイル)+語彙として宣言された環境変数(新しいスタイル)の2つの変数を組み合わせてグローバル環境変数と見なします.後者の場合、scriptのscopeとマークします.letとconstは後者なので、グローバル環境ですがwindowオブジェクトにはありません.
    ソース:Stackoverflow
    letとconstは新しく導入された文法を比較する.ブラウザjsではglobalがwindowが担当し,この分野は多くの変数に囲まれている.さらにユーザ定義のグローバル変数や定数を加えると、様々な問題が発生し、それを防止するために、ユーザ定義データを含むグローバルな範囲が発生することはありません.
    出典:生活コード
    💡 グローバル宣言の問題
    global scopeはすでに様々な値を宣言している.ライブラリなどを含めると、より多くの値が存在し、宣言まですると名前の変更や削除が悪いことが起こります.そのため、大型番組を制作する際、global scopeに声明を発表するのは適切ではない.
    fn 2関数に入りましょう.
    	n0 = "n0";
      var v0 = "v0";
      let l0 = "l0";
      const c0 = "c0";
      console.log(v0, n0, l0, c0);
      console.log(window.v0, window.n0, window.l0, window.c0);
    function fn2() {
        n2 = "n2";
        console.log(n0, n1, n2);
        var v2 = "v2";
        console.log(v0, v2);
        // console.log(v1)
        let l2 = "l2";
        console.log(l0, l2);
        // console.log(l1);
        const c2 = "c2;";
        console.log(c0, c2);
        // console.log(c1);
      }
      function fn1() {
        n1 = "n1";
        var v1 = "v1";
        let l1 = "l1";
        const c1 = "c1";
        fn2();
      }
      fn1();

    (画像:fn 2関数に入った後の変化)
    以上のように変化していることがわかります.
    fn 1()で実行されているfn 2()を表示します.親と呼べるfn 1()のLocal Scopeはfn 2()のLocalにはなく、fn 2()のLocalのみです.(LexicalScopeの理由を説明)
    この状態(fn 2 execute context範囲)で宣言した変数を実行します.上のコードのfn 2 console.ロゴ部分です
    n 0、n 1、n 2、v 0は、グローバルな範囲内で正常に動作します.
    v 2の場合、fn 2のローカル範囲にあるため、正常に動作します.
    v 1の場合、fn 1のローカル範囲内でアクセスできないためエラーが発生します.
    l 0の場合、Script scopeにあるため、正常に動作します.
    l 2の場合、fn 2のローカル範囲内であるため、正常に動作します.
    l 1の場合、fn 1のローカル範囲内でアクセスできないためエラーが発生します.
    cの場合はlと同じです.
    fn 2()のすべてのコードを実行してから出かけましょう.

    Call Stackでは、fn 2 Executeコンテキストが消えます.fn 1を離れる場合も,fn 1はCall Stackから削除され,グローバルexecuteコンテキストのみが残る.

    Lexical scope


    JavaScriptはLexicalscopeに従います.
    Lexicalscopeは、関数をどこで呼び出すかではなく、どこに宣言するかによって決定されます.
    JavaScriptはLexical Scopeに従うため、関数の宣言時に親Scopeを決定します.関数をどこから呼び出すかは、スキャン決定に何の意味もありません.
    つまり、関数の呼び出しは親スキャンではなく 宣言によって大尉を決める.
    Lexicalscopeによる次のコードの結果の予測
    var x = 1;
    
    function foo() {
      var x = 10;
      bar();
    }
    
    function bar() {
      console.log(x);
    }
    
    foo(); // ?
    bar(); // ?
    上記の例の関数barはグローバルとして宣言されます.したがって、関数バーの親スキャンはグローバルスキャンであり、上記の例ではグローバル変数xの値1を2回出力します.

    整理する



    letとconstは関数だけでなく、blockでもLocal Scopeに入ります.
    これに対して、追加学習を行います.

    以上で得られた効果


    予期せぬ問題が発生した場合、デバッガで現在のステータスを把握し、問題を解決するためのポリシーを育成できます.
    参考資料
    生活コード
    Execution Context | PoiemaWeb