こんにちは!フロントエンドからNode.jsの深層まで、日夜JavaScriptと向き合っているシニアアーキテクトです。
今回は、JavaScriptの基本中の基本でありながら、実はコードの品質や保守性を大きく左右する「変数の宣言(`let` と `const`)」についてお話しします。
「JavaScriptを書き始めたけれど、とりあえず `let` を使っておけば動くし、何が違うの?」
「他の言語では変数をあとから変えるのが当たり前だから、`const` ってなんだか窮屈そう……」
そんな風に感じていませんか?
ここをクリアすれば、あなたの書くコードの意図が劇的に明確になり、バグの温床を断つ「宣言的プログラミング」の扉が開きます。さあ、一緒にJavaScriptの本質に迫っていきましょう!
—
1. なぜ `let` よりも `const` がデフォルトであるべきなのか?
私たちがコードを書くとき、最も意識すべきことは何だと思いますか?
それは「コンピュータにどう動かしてもらうか」だけではありません。「次にこのコードを読む人間(そして未来の自分)に、自分の意図をどう伝えるか」です。
ここに、現代のJavaScript開発における大原則があります。
> 「変数は、再代入が必要であることが証明されるまで、すべて `const` で宣言せよ」
なぜ `const` がそれほど重要視されるのでしょうか? それは、`const` が「この値は、このスコープの中で一生変わりませんよ」という強力な契約(コントラクト)をコードの読み手に提示するからです。
イミュータブル(不変)がもたらす安心感
例えば、大規模なアプリケーションを開発しているとき、何百行もある関数の途中で変数の値が書き換わっていたら、デバッグ地獄になりますよね。「あれ? この変数の値、どこで変わったんだっけ……?」と、脳内スタックトレースが崩壊してしまいます。
最初から `const` を使っていれば、V8エンジンはその変数が再代入されないことを前提に最適化を行いますし、何より人間がコードを追うときの「認知負荷」が圧倒的に下がります。
—
2. 基本的な使い方と、コードの意図の読み解き方
まずは、`let` と `const` の基本的な振る舞いを確認してみましょう。
// 【ケース1】再代入が必要なカウンター(letを使用)
let visitCount = 0;
// ページが訪問されるたびにカウントアップする(再代入)
visitCount = visitCount + 1;
console.log(`本日の訪問者数: ${visitCount}人`); // 出力: 本日の訪問者数: 1人
// 【ケース2】設定値や一度決まった値(constを使用)
const SITE_NAME = ‘JS-Architect-Lab’;
// 間違って値を書き換えようとしてみる
// SITE_NAME = ‘別サイト’;
// ❌ TypeError: Assignment to constant variable.
ここで注目してほしいのは、コードを書いた瞬間の「意図の伝わり方」です。
- `let visitCount`: 「あ、この値はプログラムの実行中に変化するんだな」と分かります。
- `const SITE_NAME`: 「お、この値は固定値であって、途中で書き換わることは絶対にないんだな」と一瞬で理解できます。
他のプログラミング言語(JavaやC#など)から来た方は、「定数は大文字で書く」というルールが染みついているかもしれませんが、JavaScriptの `const` は「定数」というよりも「再代入不可の変数(バインディング)」を意味します。ですから、小文字であっても、再代入しない値であればどんどん `const` を使うのがモダンJavaScriptのスタンダードです。
—
3. 初学者が陥りがちな「`const` の勘違い」とエラーの正体
ここで、JavaScriptを学び始めた人が必ず一度はハマる罠について解説します。
「`const` を使ったのに、中身が書き換えられた!バグだ!」
次のコードを見てください。
const user = {
name: ‘Taro’,
age: 25
};
// オブジェクトのプロパティを変更してみる
user.age = 26;
console.log(user.age); // ➔ えっ、26に変わっちゃった!?
「あれ? `const` なのに値が変わったぞ? バグじゃないのか?」と慌ててしまうかもしれませんが、これは仕様通りの正しい挙動です。
メモリの仕組みから理解する `const` の正体
JavaScriptの変数とメモリ(V8ヒープ領域)の関係をイメージ図で考えてみましょう。
- `const user` が固定しているのは、オブジェクトそのものではなく、「オブジェクトが格納されているメモリ上の住所(参照)」です。
- つまり、「`user` という変数には、ずっと同じ家(オブジェクト)の住所が入っていること」は `const` によって守られています。
- しかし、「その家の中にある家具(プロパティ)の配置を変えたり、新しい家具を置いたりすること」は禁止されていません。
もし、オブジェクト自体の構造も一切変更させたくない(完全なイミュータブルにしたい)場合は、JavaScriptの標準機能である `Object.freeze()` を組み合わせます。
const config = Object.freeze({
theme: ‘dark’,
version: ‘1.0.0’
});
config.theme = ‘light’; // 厳格モード(strict mode)ではエラー、通常モードでも無視される
console.log(config.theme); // 出力: ‘dark’ (変更されない)
—
4. 宣言的プログラミングへの第一歩
「宣言的プログラミング」という言葉を聞くと難しく感じるかもしれませんが、要するに「コンピュータに『どうやって(How)』処理させるかではなく、『なにを(What)』したいのかをコードで語らせる」ということです。
`var` 全盛の時代は、スコープが歪んでバグ(巻き上げによる予期せぬ挙動)が起きやすく、「とりあえず変数を作って、あとでゴニョゴニョ書き換える」という命令的な書き方が主流でした。
しかし、`let` と `const` を適切に使い分ける現代のスタイルは、以下のようにコードの質を底上げします。
1. スコープの適正化: ブロック単位( `{}` の中)で変数が確実に閉じ込められ、外側を汚さない。
2. ミュータビリティ(可変性)の最小化: 変数を変えていい場所が限定されるため、バグの探索範囲が狭まる。
3. セルフドキュメンティング(自己文書化): コメントを書かなくても、`const` と `let` の使い分けだけでコードの意図が雄弁に語り出す。
—
まとめ:ここをクリアすれば、JavaScriptの基本はバッチリ!
いかがでしたでしょうか?
変数の宣言を `var` から `let` / `const` に切り替え、さらに「デフォルトは `const`、再代入が必要なときだけ `let`」という思考法を身につけるだけで、あなたの書くコードは見違えるほど洗練され、堅牢になります。
- すべての変数を `const` で始める。
- どうしても値を変えざるを得ないループのカウンターや状態管理でのみ `let` を採用する。
このシンプルなルールを意識するだけで、バグは劇的に減り、コードを読むストレスから解放されます。
ここをクリアしたあなたなら、もうモダンJavaScriptの波に乗る準備は万全です。明日からのコーディングで、ぜひ「宣言的思考」を試してみてくださいね!