let/const から始めるモダンJavaScript入門 – varとの違いを徹底解説

「なんとなくlet/constは使っているけど、本当の違いはよく分かってない…」 「varで動いているコードを書き換える必要があるの?」 「constって、結局どんな時に使うべきなの?」

前回、モダンJavaScriptへの移行の必要性について説明しました。今回は具体的な第一歩として、変数宣言の新しい方法であるlet/constについて解説します。これらはES6で導入された機能ですが、単なる「新しいvar」ではありません。

適切に使い分けることで、より安全で保守性の高いコードを書くことができます。

varの問題点を理解する

まず、なぜvarに代わる新しい変数宣言が必要だったのか、具体例で見ていきましょう:

JS
// 問題1: 再宣言が可能
var message = "Hello";
var message = "World"; // エラーにならない

// 問題2: 変数の巻き上げ(ホイスティング)
console.log(user); // undefined(エラーにならない)
var user = "John";

// 問題3: ブロックスコープがない
if (true) {
    var count = 1;
}
console.log(count); // 1(ブロックの外からアクセス可能)

これらの振る舞いは、意図しないバグを引き起こす原因となっていました。特に大規模なアプリケーションでは、変数名の衝突やスコープの問題が深刻化していきます。

letによる改善

letは、これらの問題を解決する新しい変数宣言方法です:

JS
// 再宣言はエラーに
let message = "Hello";
let message = "World"; // SyntaxError

// 初期化前の参照はエラーに
console.log(user); // ReferenceError
let user = "John";

// ブロックスコープの導入
if (true) {
    let count = 1;
}
console.log(count); // ReferenceError

letの特徴

1.ブロックスコープ

JS
let temperature = 20;

if (temperature > 15) {
    let message = "暖かい";
    console.log(message); // "暖かい"
}

console.log(message); // ReferenceError

2.一時的なデッドゾーン(TDZ)

JS
{
    // ここからletの宣言までがTDZ
    // console.log(value); // ReferenceError
    let value = 42;
    console.log(value); // 42
}

constで不変性を獲得する

constは、さらに一歩進んで変数の再代入を防ぎます:

JS
const API_KEY = "abc123";
API_KEY = "xyz789"; // TypeError

// ただし、オブジェクトのプロパティは変更可能
const config = {
    theme: "dark"
};
config.theme = "light"; // OK
config = {}; // TypeError

constの使い所

1.設定値やマジックナンバーの置き換え

JS
const MAX_ATTEMPTS = 3;
const DEFAULT_THEME = "light";
const API_ENDPOINT = "https://api.example.com";

2.関数宣言

JS
const calculateTax = (amount, rate) => amount * rate;

3.オブジェクトやクラスのインスタンス

JS
const user = {
    name: "John",
    age: 30
};

const userList = [];
userList.push(user); // 配列の内容は変更可能

実践的な使い分け

以下のような基準で使い分けることをお勧めします:

1.デフォルトはconst

  • 変数の値が変更される必要がない場合
  • オブジェクトや配列の参照
  • 関数宣言

2.必要な場合にlet

  • ループのカウンター
  • 状態を変更する必要がある変数
  • 累積値の計算
JS
const items = ["apple", "banana", "orange"];
let total = 0;

for (let i = 0; i < items.length; i++) {
    const item = items[i];
    total += item.length;
}

jQueryコードのモダン化例

実際のjQueryコードを書き換えてみましょう:

JS
// Before: jQuery with var
var $button = $('#submit');
var clickCount = 0;

$button.click(function() {
    var message = 'Clicked!';
    clickCount++;
    $(this).text(message + ' ' + clickCount);
});

// After: Modern JavaScript with let/const
const submitButton = document.querySelector('#submit');
let clickCount = 0;

submitButton.addEventListener('click', function() {
    const message = 'Clicked!';
    clickCount++;
    this.textContent = `${message} ${clickCount}`;
});

まとめ

let/constの導入は、単なる構文の変更ではありません。これらを適切に使うことで:

  • 意図しない変数の再代入を防げる
  • スコープをより厳密に制御できる
  • コードの意図をより明確に表現できる

といったメリットが得られます。次回は「アロー関数とthisの振る舞い」について解説し、さらにコードをモダンに進化させていきましょう。