Java Script スコープ

スコープとは

変数や関数を「参照できる範囲」のこと

スコープには3種類ある

  1. グローバルスコープ
  2. ブロックスコープ
  3. モジュールスコープ

グローバルスコープ

  • グローバルスコープとは、プログラム全体から参照できるスコープのこと。
  • type="module" が指定されていない場合、ファイルの先頭レベルで宣言した変数や関数はグローバルスコープに属し、どこからでもアクセスできる。
  • ファイル全体、ブラウザ環境では window オブジェクトに紐づく。

・宣言、定義される場所 

  • type="module" が指定されていない <script> タグ直下の {} で囲まれていない場所
  • type="module" でない外部 JavaScript ファイルの {} で囲まれていない場所

・特徴・注意点

  • 変数名の衝突が起きやすい
  • どこで変更されたか追いにくく、保守性が低下しやすい
  • 宣言なしで代入すると、意図せずグローバル変数が作成される(※非 strict 時)
  • var は関数スコープのため、スコープの誤解を招きやすい

※ JavaScript では、var や宣言なし代入は条件次第でグローバル変数を作ってしまうが、let と const はグローバル汚染を防ぐ

JavaScript
// let / const(正解)
let message = "Hello"; // グローバルスコープ

function greet() {
  console.log(message); // どこからでも参照できる
}

greet();
JavaScript
//宣言なし代入(完全にNG)
function bad() {
  x = 5; // 宣言なし代入(暗黙的にグローバル変数が作られる)
  return x;
}
bad();
console.log(); //・・・5  どこからでも参照できてしまう
JavaScript
//var(動くが好ましくない)
function bad() {
  if (true) {
    var x = 5;
  }
  return x; // 5 ← if を抜けても生きている
}

console.log(bad());

ブロックスコープ

  • {}(ブロック)単位で有効なスコープ
  • letconst のみ対象
  • if / for / while / try などで発生
JavaScript
if (true) {
  let a = 1;
  const b = 2;
}
console.log(a); // エラー
ブロックスコープの特徴
1.子ブロックで宣言された変数・定数・関数は、親ブロックから参照できない
    JavaScript
    {
      const x = 1;
    }
    console.log(x); // ReferenceError
    • ブロックスコープは 内側で宣言したものは外に出ない
    • let / const / class / (block内function) が対象
    2.親ブロックで宣言された変数・定数・関数は、子ブロックから参照できる
    JavaScript
    {
      const x = 1;
      {
        console.log(x); // 1
      }
    }
      • これは スコープチェーン
      • 内側は外側を参照できる
      3.同一スコープ階層にある別ブロック間では、変数・定数・関数を相互に参照できない
      JavaScript
      {
        const a = 1;
      }
      
      {
        console.log(a); // ReferenceError
      }
      • 並列なブロック同士は無関係
      • スコープチェーンがつながっていない

      モジュールスコープ

      • ES Modules(type=”module”)で有効
      • ファイル単位で独立したスコープ
      • グローバルを汚染しない

      コメント