JavaScript 逆引き集 | スコープと var/let/const の違い

JavaScript JavaScript
スポンサーリンク

スコープと var / let / const の違い — var は関数スコープ、let / const はブロックスコープ

JavaScript で変数を宣言するときに使うキーワードは var / let / const の3種類があります。
初心者が混乱しやすいのが「スコープ(有効範囲)」の違いです。


基本の違い

キーワードスコープの種類再宣言再代入特徴
var関数スコープ可能可能古い書き方。ブロック {} を無視する
letブロックスコープ不可可能現代的な変数宣言。ブロックごとに有効
constブロックスコープ不可不可定数。値を変えられない(ただしオブジェクトの中身は変更可能)

コード例で理解する

1. var は関数スコープ

function testVar() {
  if (true) {
    var x = 1; // ifブロック内で宣言
  }
  console.log(x); // → 1 (ブロックを抜けても使える)
}
testVar();
JavaScript
  • ポイント: var は「関数全体」で有効。iffor の中で宣言しても外で使える。

2. let / const はブロックスコープ

function testLetConst() {
  if (true) {
    let y = 2;
    const z = 3;
    console.log(y, z); // → 2 3
  }
  console.log(y); // エラー: y is not defined
}
testLetConst();
JavaScript
  • ポイント: let / const は「ブロック {} の中だけ」で有効。外に出ると消える。

3. 再宣言と再代入の違い

var a = 1;
var a = 2; // 再宣言OK
console.log(a); // → 2

let b = 1;
// let b = 2; // エラー: 再宣言不可
b = 2; // 再代入はOK
console.log(b); // → 2

const c = 1;
// const c = 2; // エラー: 再宣言不可
// c = 2;       // エラー: 再代入不可
console.log(c); // → 1
JavaScript

よく使うテンプレート集

forループでの違い

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log("var:", i), 100);
}
// → var: 3, var: 3, var: 3 (全部3)

for (let j = 0; j < 3; j++) {
  setTimeout(() => console.log("let:", j), 100);
}
// → let: 0, let: 1, let: 2 (期待通り)
JavaScript
  • 理由: var はループ全体で1つの変数。let はループごとに新しい変数。

定数オブジェクトの中身は変更可能

const obj = { name: "Aki" };
obj.name = "Mika"; // プロパティは変更できる
console.log(obj.name); // → "Mika"
JavaScript

例題: 簡易カウンター

function makeCounter() {
  let count = 0; // ブロックスコープで外から触れられない
  return () => ++count;
}

const counter = makeCounter();
console.log(counter()); // 1
console.log(counter()); // 2
JavaScript
  • 効果: countlet で宣言されているので外から直接アクセスできない。
  • ポイント: var だとスコープが広すぎて意図せず外から触れてしまうことがある。

実務でのコツ

  • 基本は let / const を使う。
  • var は古いコードでしか使わない。
  • 値を変えないなら const、変えるなら let
  • ブロックスコープを意識するとバグが減る。

ありがちなハマりポイントと対策

  • var で意図せず上書き:
    • 対策: let / const を使う。
  • const でオブジェクトを変更できるのに驚く:
    • 対策: 「変数の再代入不可」であって「中身の変更不可」ではない。
  • ループで var を使うと値が共有される:
    • 対策: let を使う。

練習問題(スコープ確認)

function scopeTest() {
  if (true) {
    var x = "var変数";
    let y = "let変数";
    const z = "const変数";
  }
  console.log(x); // → "var変数"
  console.log(y); // エラー
  console.log(z); // エラー
}
scopeTest();
JavaScript
  • 効果: var は関数スコープなので外でも使えるが、let / const はブロック内だけ。

直感的な指針

  • var = 古い書き方。関数スコープ。
  • let = 現代的な変数。ブロックスコープ。
  • const = 定数。ブロックスコープ。
  • 基本は const、必要なら letvar は使わない。

これを覚えれば「変数の有効範囲」「再代入の可否」を理解でき、バグの少ないコードが書けるようになります。

タイトルとURLをコピーしました