JavaScriptプログラムを開発する際、変数の宣言は避けて通れない基本的な作業です。
かつてのJavaScriptではvarによる宣言が主流でしたが、現代のJavaScript開発においては値を再代入しない変数はすべて定数として定義することが推奨されています。
定数を正しく使いこなすことは、プログラムのバグを減らし、コードの意図を明確にするために非常に重要です。
本記事では、JavaScriptにおける定数宣言の基本から、間違いやすいオブジェクトや配列の扱い、そして2026年現在の開発現場で求められる命名規則まで、実務に役立つ知識を詳しく解説します。
JavaScriptにおける定数の役割と重要性
プログラミングにおける定数とは、一度値を決めたら後から変更することができない変数のことを指します。
JavaScriptでは、ES2015(ES6)で導入されたconstキーワードを使用して定数を宣言します。
なぜ定数を使う必要があるのでしょうか。
その最大の理由はプログラムの予測可能性を高めるためです。
コードのどこかで意図せず値が書き換えられてしまうと、予期せぬ動作やデバッグの困難なバグを引き起こします。
最初から「この値は変わらない」と宣言しておくことで、コードを読む人(将来の自分を含む)に対して、その値の役割を保証することができます。
また、現代のJavaScriptエンジンは定数に対して高度な最適化を行います。
値が変わらないことが確実であれば、実行時のパフォーマンス向上が期待できるというメリットもあります。
constによる定数宣言の基本
まずはconstの基本的な書き方と、その性質について確認しましょう。
再代入の禁止と初期化
constを使用して宣言された変数には、新しい値を再代入することができません。
また、宣言と同時に必ず初期値を割り当てる(初期化する)必要があります。
// 正しい書き方:宣言と同時に初期化する
const MAX_USER_COUNT = 100;
console.log(MAX_USER_COUNT);
// 誤った書き方1:初期化せずに宣言する
// const MIN_USER_COUNT; // SyntaxError: Missing initializer in const declaration
// 誤った書き方2:値を再代入する
// MAX_USER_COUNT = 200; // TypeError: Assignment to constant variable.
100
上記のように、値を再代入しようとするとTypeErrorが発生し、プログラムの実行が停止します。
これにより、開発段階で誤った代入を検知できるのが大きな利点です。
ブロックスコープの特性
constは「ブロックスコープ」を持ちます。
これは、{}(波括弧)で囲まれた範囲内でのみ有効であることを意味します。
const message = "Global Message";
if (true) {
const message = "Local Message";
console.log("Inside block:", message);
}
console.log("Outside block:", message);
Inside block: Local Message
Outside block: Global Message
以前のvarでは関数スコープであったため、条件分岐やループの中で宣言した変数が外に漏れ出す問題がありましたが、const(およびlet)ではその心配がありません。
定数の命名規則:読みやすく保守しやすいコードのために
定数の名前をどのように付けるかは、チーム開発の効率に直結します。
JavaScriptでは、定数の性質によって大きく2つの命名規則を使い分けるのが一般的です。
基本はキャメルケース (camelCase)
通常の処理の中で一度だけ値を代入して使い回すようなローカルな定数には、キャメルケースを使用します。
これは、最初の単語を小文字で始め、以降の単語の頭文字を大文字にする形式です。
const userData = await fetchUserData();
const filteredList = items.filter(item => item.isActive);
const responseTime = 150;
現代のJavaScript開発では、値が変化しない限りすべてconstで書く「const-first」という考え方が主流です。
そのため、すべてのconstを大文字にするのではなく、通常の変数名と同じ感覚でキャメルケースを用いるのが標準的です。
「真の定数」は大文字スネークケース (SCREAMING_SNAKE_CASE)
アプリケーション全体で共有される設定値、物理的な定数、マジックナンバーの代替となるような値には、大文字のスネークケースを使用します。
これは、すべての文字を大文字にし、単語をアンダースコアで繋ぐ形式です。
const API_BASE_URL = "https://api.example.com/v1";
const DEFAULT_TIMEOUT_MS = 5000;
const MAX_RETRY_ATTEMPTS = 3;
このように記述することで、コードを読んでいる時に「これはソースコードのどこかで計算された結果ではなく、静的に定義された固定値である」ということが一目で伝わります。
| 命名規則 | 用途 | 例 |
|---|---|---|
| camelCase | 一般的な定数、計算結果、関数の戻り値 | userList, isLoaded |
| SCREAMING_SNAKE_CASE | 設定値、環境変数、魔法の数字(マジックナンバー) | APP_PORT, COLORS_PRIMARY |
constとオブジェクト・配列の挙動
JavaScriptのconstに関して、初心者が最も混乱しやすいのがオブジェクトや配列の扱いです。
「constで宣言したからといって、中身が全く変更できなくなるわけではない」という点に注意が必要です。
プロパティや要素の変更は可能
constが禁止しているのは、あくまで変数そのものへの再代入です。
オブジェクトのプロパティを書き換えたり、配列の要素を追加・削除したりすることは制限されません。
const user = {
id: 1,
name: "Tanaka"
};
// プロパティの変更はOK
user.name = "Sato";
// プロパティの追加もOK
user.age = 25;
console.log(user);
const numbers = [1, 2, 3];
// 配列のメソッドによる変更はOK
numbers.push(4);
numbers[0] = 10;
console.log(numbers);
// 再代入はNG
// user = { id: 2 }; // TypeError
{ id: 1, name: 'Sato', age: 25 }
[ 10, 2, 3, 4 ]
なぜ値の変更が許可されるのか
これは、JavaScriptにおける「参照型」というデータ構造の仕組みによるものです。
constで保持しているのは、オブジェクトや配列の本体ではなく、そのデータが格納されているメモリ上の場所(参照情報)です。
「参照情報そのもの」を書き換える(=別のオブジェクトを代入する)ことはconstによって防がれますが、その参照先にあるデータの中身をいじることは制限の対象外なのです。
この性質を正しく理解していないと、不変だと思っていたデータが意図せず変更されてしまうトラブルに繋がります。
オブジェクトの完全な定数化:Object.freeze()の活用
もし、オブジェクトのプロパティも一切変更させたくない場合は、JavaScript標準のObject.freeze()メソッドを使用します。
Object.freeze()の使い方
このメソッドを使用すると、オブジェクトが「凍結」され、プロパティの追加、削除、変更が一切できなくなります。
"use strict"; // strictモードを推奨
const SYSTEM_CONFIG = Object.freeze({
theme: "dark",
version: "2.0.0"
});
// 変更を試みる
// SYSTEM_CONFIG.theme = "light"; // TypeError (strictモード時)
console.log(SYSTEM_CONFIG.theme);
dark
Object.freeze()を使用する場合、use strict環境下ではエラーが投げられますが、そうでない場合はエラーが出ずに無視されるだけになるため、基本的にはstrictモード(厳格モード)での使用が前提となります。
ネストされたオブジェクトへの注意点
一つ注意が必要なのは、Object.freeze()は「浅い(シャロー)凍結」であるという点です。
オブジェクトの中にさらにオブジェクトが含まれている場合、内側のオブジェクトまでは保護されません。
const nestedObj = Object.freeze({
outer: "value",
inner: {
item: "A"
}
});
nestedObj.outer = "changed"; // 無効
nestedObj.inner.item = "B"; // 有効(変更されてしまう)
console.log(nestedObj.inner.item);
B
深い階層まで完全に定数化したい場合は、再帰的にフリーズをかけるライブラリを利用するか、独自にディープフリーズ用の関数を用意する必要があります。
2026年現在のモダンなフロントエンド開発(Reactなど)では、状態の不変性(イミュータビリティ)を守るために、こうしたオブジェクトの扱いには特に注意を払います。
varやletとの使い分け基準
ここまで定数constについて解説してきましたが、他の宣言キーワードとの使い分けについても整理しておきましょう。
- const:デフォルトでこれを使う。値を再代入する必要がないすべてのケース。
- let:ループのカウンタ変数や、後から値を上書きする必要がある計算用変数など、再代入が必要な場合のみ使う。
- var:現代のコードでは原則として使用しない。スコープの曖昧さや意図しない巻き上げの問題があるため、レガシーコードの保守以外で選ぶ理由はありません。
開発時のベストプラクティスは、「まずすべてをconstで書き、どうしても再代入が必要になった時だけletに変更する」というアプローチです。
このルールを徹底するだけで、コードの品質は劇的に向上します。
まとめ
JavaScriptの定数constは、単に「値を変えない」ための機能以上の役割を持っています。
それは、開発者の意図をコードに込め、システムの安定性を高めるための強力なツールです。
本記事で解説した重要ポイントを振り返りましょう。
constは再代入を禁止し、宣言時の初期化を必須とする。- ブロックスコープを持ち、安全な変数管理が可能。
- 命名規則として、通常はキャメルケース、不変の設定値などは大文字スネークケースを用いる。
- オブジェクトや配列の場合、
constだけでは中身の変更を防げない。 - 完全に中身を固定したい場合は
Object.freeze()を併用する。
2026年のJavaScript開発においても、これらの基礎知識は変わらず不可欠なものです。
定数を正しく使い分け、堅牢で読みやすいプログラムを目指しましょう。
より高度な開発を目指すなら、TypeScriptなどの型システムを導入して、より厳格な定数管理を学ぶのも良いでしょう。
