178日目-スキャンとクローズ


JavaScriptの勉強を始めて19日目にScopeとCloserに言及しました.
私は覚えていません.ブログを振り返ったとき、後で整理すると言っただけで、整理していませんでした.今日は片付けたばかりです.

スキャン


スコフは名前のように、範囲に関する内容です.
では、どんな範囲についてですか.
すべての識別子(変数名、関数名、クラス名など)は、宣言された場所によって、他のコード参照識別子自体の有効範囲を決定します.これはスコプフと呼ばれています.すなわち,スキャンは指標識別子の有効範囲である.
前述したように、参照可能な有効範囲である.
大分、全域スキャン/領域スキャンの2種類に分けられます.

ぜんきょくけい


グローバルスキャンは、ブロック外で宣言された変数を例に挙げることができます.これらの変数をグローバル変数と呼びます.
宣言はブロックの外にあるため、ブロックの内部を含むどこからでもアクセスできます.
const globalVariable = '전역변수';

function global () {
  return globalVariable
}

global() // '전역변수';
グローバル変数の使用は、変数の名前の重複と予期せぬ再割り当てによるステータスの変化のため、コードの予測が困難になります.

ゾーンスキャン


領域スキャンは、関数スキャンとブロックスキャンに分けられます.

かんすうそういん

  • JavaScriptは基本的に関数スキャンに従います.これは、新しい関数が生成されるたびに新しいスキャンが生成されることを意味します.
  • 関数で宣言された変数は、その関数にのみアクセスできます.
  • function sayHi () {
      const hi = 'hi';
      return hi;
    }
    
    sayHi(); // 'hi'
    console.log(hi) // error, hi가 정의되지 않음

    ブロックミラー

  • ブロックスキャンは、1つのブロック({})が生成されるたびに新しいスキャンを形成する.
  • の元のjavascriptは関数スキャンに従うが、letとconstキーワードの出現はブロックスキャンの形成を可能にした.
  • {
      const hi = 'hi'
      console.log(hi); // 'hi'
    }
    console.log(hi); // error, hi가 정의되지 않음

    レプリカ


    まずCloser定義を見てみましょう
    関数と関数が宣言された語彙環境の組合せ.この環境は、モジュールの作成時に有効な範囲内のすべての領域変数から構成されます.

    ここで、語彙環境が何なのか知りたいので、MDNを探しました。例は以下の通りです。

    function init() {
      var name = "Mozilla"; // name은 init에 의해 생성된 지역 변수이다.
      function displayName() { // displayName() 은 내부 함수이며, 클로저다.
        alert(name); // 부모 함수에서 선언된 변수를 사용한다.
      }
      displayName();
    }
    init();
    displayName()内部には領域変数はありませんが、関数内部から外部関数の変数にアクセスできるため、displayName()は親関数init()で宣言された変数名にもアクセスできます.
    displayName()関数の内部に変数nameがある場合は、nameではなくthisを使用します.名前を使ったはずです.
    上記のコードを実行すると、displayName()関数のalert()文が親関数で定義した変数nameの値を正常に出力します.
    これは、語彙範囲(語彙範囲)の一例です.ここで、「語彙」は、語彙範囲(語彙範囲)中に変数がどこで使用可能かを知るために、ソースコードのどこで変数を宣言するかを考慮することを意味します.単語「語彙」はこのような事実を表す.ネスト関数は、外部範囲(scope)で宣言された変数にもアクセスできます.
    最初は分かりづらいのですが、ずっと読んでいたので理解しました.
    関数呼び出し中に内部語彙環境で変数を検索する場合、内部語彙環境に外部がなくても、グローバルlexacial環境を語彙環境として理解できます.
    だから、語彙環境との組み合わせは何なのか、なぜモジュールが特別なのか.
    一般関数は、関数の実行が終了した後、関数内部の変数を使用できません.ただし、モジュールは、外部関数の実行が完了しても、外部関数の変数をメモリに格納します.
    上記の特徴から,語彙環境の組合せと呼ぶ.
    以下に例を示します.

    プラス記号

    const adder = x => y => x + y;
    
    const add3 = adder(3);
    add3(5); // 8
    add3(10); // 13

    モジュールを使用したラベルの作成

    const tagMaker = tag => innerText => `<${tag}>${innerText}</${tag}>`;
    
    const divMaker = tagMaker('div');
    divMaker('hello'); // '<div>hello</div>'
    divMkaer('world'); // '<div>world</div>'
    外部関数の実行が終了しても、外部関数の変数が保存されていることがわかります.
    また,Closerのもう一つの特徴は隠匿化である.
    関数宣言時の語彙環境は、外部からのアクセスでは変更できないことを覚えています.

    参考資料


    現代JavaScript Deep Dive-李雄模知音
    PoiemaWebスキャン
    Howdy-Scope
    PoiemaWeb-エンクロージャ
    MDN-シャーシ
    エンコーディングモジュール
    学習コードフェーズ-モジュールの使用例