スコープ

変数や関数が参照可能な範囲を定義するプログラミングの基本概念

JavaScript基礎

スコープとは

スコープ (Scope) は、変数や関数が参照可能な範囲を定義するプログラミングの基本概念である。JavaScript には、グローバルスコープ、関数スコープ、ブロックスコープの 3 種類がある。

スコープの種類

スコープ 宣言 範囲
グローバル トップレベル どこからでも参照可能
関数 var, function 関数内のみ
ブロック let, const {} 内のみ

var vs let vs const

// var: 関数スコープ (ブロックを無視)
if (true) { var x = 1; }
console.log(x); // 1 (ブロックの外でも参照可能)

// let: ブロックスコープ
if (true) { let y = 2; }
console.log(y); // ReferenceError (ブロックの外では参照不可)

// const: ブロックスコープ + 再代入不可
const z = 3;
z = 4; // TypeError: Assignment to constant variable

レキシカルスコープ

const outer = 'outer';

function foo() {
  const inner = 'inner';
  console.log(outer); // ✅ 外側のスコープを参照可能
}

console.log(inner); // ❌ ReferenceError
// JavaScript はレキシカルスコープ: 定義時のスコープで変数を解決

クロージャとスコープ

function createCounter() {
  let count = 0; // createCounter のスコープ
  return () => ++count; // クロージャ: count を記憶
}
const counter = createCounter();
counter(); // 1
counter(); // 2
// count は外部からアクセスできないが、返された関数からは参照可能
スコープ Lambda での挙動
モジュールスコープ コールドスタート時に初期化、ウォームスタートで再利用
ハンドラスコープ 毎回のリクエストで新規作成

スコープの落とし穴

// ❌ var + ループ: 全て同じ i を参照
for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 3, 3, 3
}

// ✅ let: 各反復で新しいスコープ
for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 100); // 0, 1, 2
}

ベストプラクティス

プラクティス 理由
const をデフォルトで使う 再代入を防止
let は再代入が必要な場合のみ スコープが明確
var は使わない 関数スコープで予期しない挙動
グローバル変数を避ける 名前の衝突、テスト困難

詳しくは関連書籍を参照。

関連用語