関数スコープとは何か
関数スコープとは、「関数の中で宣言された変数は、その関数の中だけで有効」という範囲のことです。外からは見えず、関数が終われば使えなくなります。JavaScriptでは伝統的に var が「関数スコープ」を持ち、let と const は「ブロックスコープ」を持つ、という違いがあるのが重要ポイントです。関数ごとに変数の見える範囲を区切ることで、外部への影響を防ぎ、意図を限定できます。
実行コンテキストとの関係を直感でつかむ
関数を呼び出すと「関数実行コンテキスト」が作られ、そこで関数スコープが用意されます。探し方の順番は「まず関数の中(ローカル)→ それでもなければ外側 → 最後にグローバル」。関数が終了すると、その関数スコープは原則使えなくなります(ただし、クロージャで参照が残る場合は別)。ここが重要です:関数の中で宣言した変数は、その呼び出し中だけの“安全な箱”であり、外部に漏らさない設計が標準です。
例題で理解する(関数内に閉じ込める感覚)
例題1:関数の外から見えない
function hello() {
const message = "こんにちは";
console.log(message);
}
hello(); // こんにちは
console.log(message); // エラー: message は定義されていません
JavaScriptmessage は hello 関数の中だけで有効です。外からは参照できず、関数スコープに守られています。
例題2:var は関数スコープ(ブロックでは区切れない)
function demo() {
if (true) {
var x = 1; // 関数スコープ(ブロックは関係ない)
}
console.log(x); // 1(if の外でも見える)
}
demo();
JavaScriptvar はブロック {} では囲い込めず、関数スコープに属します。これが予期せぬ可視化の原因になりやすい点を覚えておきましょう。
例題3:let/const はブロックでさらに狭くなる
function demo() {
if (true) {
const y = 2; // ブロックスコープ
console.log(y); // 2
}
console.log(y); // エラー: y は定義されていません
}
demo();
JavaScript同じ「関数の中」でも、let/const はブロックごとにスコープを分けます。関数スコープの中にさらに小さな“部屋”があるイメージです。
影響範囲を見極める(重要ポイントを深掘り)
関数スコープの本質は「外部の状態を不用意に汚さない」ことです。関数の中で完結する短命の変数を閉じ込めると、衝突や上書きのバグを防げます。ここが重要です:
- 関数の入口(引数)と出口(戻り値)以外で外部に触る行為(グローバル更新など)は副作用になり、テストや再利用を難しくします。
varはブロックで区切れないため、意図しない共有が起きがち。基本はlet/constを使い、必要ならさらにブロックスコープで範囲を絞るのが安全です。
関数スコープを活かす設計の感覚
関数は「入力(引数)を受け、内部で処理し、結果(戻り値)だけを返す箱」として設計すると、外部と疎結合になり、テストしやすく読みやすいコードになります。関数内の変数は外から見えないため、名前を自由につけても衝突しません。必要な設定値は引数で渡すか、モジュールスコープで明示的に共有し、関数内の短命な値は関数スコープに閉じ込めましょう。
function priceWithTax(price, taxRate) {
const taxed = Math.floor(price * (1 + taxRate)); // 関数内だけの一時変数
return taxed; // 外へは結果だけ返す
}
console.log(priceWithTax(1000, 0.1)); // 1100
JavaScriptまとめ
関数スコープは「関数内で宣言した変数は関数内だけで有効」というルールで、外部を汚さず安全に処理を閉じ込める仕組みです。var は関数スコープでブロックに閉じ込められない一方、let/const は関数スコープの中にさらにブロックスコープを作れます。副作用を避け、引数と戻り値でデータをやり取りする設計を心がけると、関数スコープの強みが生き、予測しやすく保守しやすいコードになります。
