【実務・中級編】 再宣言の可否とルール – JavaScript実践ガイド

現場で戦っていると、たまに「なぜJavaScriptはこうなっているのか?」と立ち止まりたくなる瞬間があるはずだ。特に変数の宣言。`var`、`let`、`const`の使い分けは、現代のフロントエンド開発における「基礎中の基礎」だが、いざ深いところまで突っ込まれると、言葉に詰まるエンジニアも少なくない。

今日は、あえて「再宣言」という切り口から、JavaScriptという言語が辿ってきた歴史と、その設計思想の核心に迫ってみよう。

—

なぜJavaScriptは「再宣言」を許してしまったのか(あるいは、禁止したのか)

まず歴史的な背景を話そう。`var`が登場した当時のJavaScriptは、今のような大規模なSPA(Single Page Application)を作るための言語じゃなかった。「ブラウザでちょっとした動きを付けるためのスクリプト」だったんだ。

そのため、多少の「曖昧さ」は許容されていた。その最たるものが`var`の再宣言だ。

var user = “Alice”;
// 数百行後…知らずに同じ変数名を使ってしまう
var user = “Bob”;
console.log(user); // “Bob” に上書きされるが、エラーは出ない

この「エラーが出ない」というのは、小規模なコードなら楽だが、現在の数万行規模のフロントエンドアプリケーションでは「悪夢」そのものだ。どこかで誰かが意図せず上書きした値が、画面の表示バグを引き起こす。このデバッグほど、無駄で疲れるものはない。

—

現代のスタンダード:let と const の守備範囲

ES6(ECMAScript 2015)で`let`と`const`が登場した最大の理由は、この「曖昧さ」を排除し、予測可能なコードを書くためだ。

再宣言のルール比較

| 宣言 | 再宣言 | 再代入 | スコープ |
| :— | :— | :— | :— |
| `var` | 可能 | 可能 | 関数スコープ |
| `let` | 不可 | 可能 | ブロックスコープ |
| `const` | 不可 | 不可 | ブロックスコープ |

`let`と`const`は、同じスコープ内での再宣言を「言語レベルで拒絶」する。これは、ブラウザのエンジンがコードをパース(解析)する段階で、「おい、同じ名前の変数がもうあるぞ」とコンパイルエラー(正確にはReferenceErrorに近い挙動)を投げる仕組みになっている。

—

実務で意識すべき「ブロックスコープ」という安全性

`var`が「関数単位」でしかスコープを作れなかったのに対し、`let`と`const`は「`{}`(ブロック)」を境界線にする。これがどれだけ強力か、以下の例を見てほしい。

function processData() {
let status = “initial”;

if (true) {
// ブロック内で同じ名前を使っても、外側とは別物として扱われる
let status = “active”;
console.log(status); // “active”
}

console.log(status); // “initial”(外側の値は守られている!)
}

もしこれが`var`だったら、`if`ブロック内の`status`が外側の`status`を書き換えてしまい、その後のロジックが崩壊する。再宣言を禁止し、スコープを狭く絞ることは、自分の書いたコードの「影響範囲」をコントロールする、最も賢い防衛策なんだ。

—

伝説のチーフアーキテクトからの一言:なぜ「const」を優先すべきか

現場のコードレビューでよく言うことがある。「迷ったらまず`const`を使え。`let`を使うのは、値の変更が確定している時だけにしろ」と。

これは単なる好みの問題じゃない。「この変数は後で変わらない」と宣言することは、コードを読む未来の自分やチームメンバーへの強力なメッセージになる。

// 良い例:意図が明確
const API_ENDPOINT = “https://api.example.com”;
const userList = fetchUserList(); // 配列やオブジェクトの中身は変えられても、参照先は固定

// 悪い例:変数の目的が曖昧
let data = fetchData();
// …長い処理…
data = transform(data); // 途中で中身が変わる可能性があると、読む側に負荷がかかる

—

まとめ:我々はどう書くべきか

1. `var`は過去の遺物として封印する:現代のプロジェクトで`var`を使う理由は一つもない。
2. `const`をデフォルトにする:変数を宣言する際は、まず`const`が使えないか考える。
3. `let`は「再代入が必要な場合」のみに限定する:カウンターや、ループの変数など、値の変化が不可避な場合のみに絞る。

JavaScriptの変数は、ただの箱じゃない。あなたが書くロジックの「信頼性」を担保する基盤だ。再宣言を許さないという仕様は、まさにフロントエンドが成熟した証とも言える。

このルールを守るだけで、君のコードのバグは劇的に減るはずだ。さあ、エディタを開いて、まずは不用意な`let`を`const`に書き換えるところから始めてみないか?

コメント

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