JavaScriptを学び始めたときに混乱するのが「変数宣言」ですよね。
「let / var / constの3種類の変数宣言キーワードがあるけど、どれを使えばいいの?」と悩んでいる方が多いのではないでしょうか。
このページでは、各変数宣言キーワードの違いや、使い方などを初心者の方にも分かりやすく解説しています。
違いが分からないけど、なんとなく使っているという方も、ぜひ参考にしてみてくださいね。
ノーノちゃん
varを使わずにletとconstを使うって書いてあったよ。letとconstを使うことをおすすめします。それについても書いていますのでよければチェックしてみてください。
ぶたさん
このページの目次
1. 変数宣言とは?

まずはじめに変数宣言について解説します。
これを理解していないと、次に進んでも混乱してしまいますのでしっかり把握しておきましょう。
どんな変数を作るかを伝えるもの

変数宣言とは、「◯◯という名前の変数(箱)を作ります」とプログラムに伝えるためのものです。
たとえば、学校の授業中にいきなり手を上げた場合、なぜ手を上げたのか伝えないと先生は困ってしまいますよね。
- 「質問があります」
- 「トイレに行きたいです」
- 「体調が悪いので保健室に行きたいです」
このように手を上げた理由を伝えることで、先生は適切に対応することができます。
JavaScriptも同じで、プログラムが適切に対応できるように、あらかじめ変数(箱)を作ることを伝えておく必要があります。
そのために行うのが変数宣言です。
ノーノちゃん
ぶたさん
変数宣言キーワードとは?

変数宣言キーワードとは、プログラムに「こういう種類の変数(箱)を作ります」と伝えるためのものです。
JavaScriptには次のように3種類の変数宣言キーワードがあります。
| 変数宣言 キーワード |
特徴 |
|---|---|
var |
・何度も同じ名前で変数(箱)を作れる ・中身はあとから自由に変えられる |
let |
・同じ名前の変数(箱)は一度しか作れない ・中身はあとから自由に変えられる |
const |
・同じ名前の変数(箱)は一度しか作れない ・一度中身を入れたら変えられない |
ぶたさん
変数宣言の使い方とは?

変数宣言
変数宣言のやり方は、まず変数宣言キーワードを書き、そのあとに変数名(箱の名前)を書きます。
let a;
| コード | 分類 | 意味 |
|---|---|---|
let |
変数宣言キーワード | 「中身を変えられる箱を作ります」という宣言 |
a |
変数名 | 作成する箱の名前 |
; |
区切り記号 | 文末につける区切り |
変数宣言キーワードletを使って「aという名前の変数(箱)を作ります」とプログラムに伝えています。
ノーノちゃん
ぶたさん
代入
代入のやり方は、まずはじめに変数宣言を書き、その下に「変数 = 変数に入れたい値」を書きます。
let a; //変数宣言
a = 1; //代入
| コード | 分類 | 意味 |
|---|---|---|
let |
変数宣言キーワード | 「中身を変えられる箱を作ります」という宣言 |
a |
変数名 | 作成する箱の名前 |
= |
代入演算子 | 右のものを左に入れる |
1 |
変数値 | 箱(a)の中に入れるデータ |
; |
区切り記号 | 文末につける区切り |
まずはじめに、変数宣言キーワードletを使って「aという名前の変数(箱)を作ります」とプログラムに伝えています。
そのあと、先ほど作った「aという箱の中に、1というデータを入れますよ」と伝えています。
ノーノちゃん
ぶたさん
定義(初期化)
let a = 1; //変数宣言 + 代入
| コード | 分類 | 意味 |
|---|---|---|
let |
変数宣言キーワード | 「中身を変えられる箱を作ります」という宣言 |
a |
変数名 | 作成する箱の名前 |
= |
代入演算子 | 右のものを左に入れる |
1 |
変数値 | 箱(a)の中に入れるデータ |
; |
区切り記号 | 文末につける区切り |
これは変数宣言と代入をまとめて書いた例です。
このように変数宣言と代入を同時に行うことを「定義(初期化)」といいます。
一般的にコードを書くときは、行数を減らして読みやすくするために、変数宣言と代入をまとめて書くことが多いです。
constの場合は分けて書くとエラーになりますので、基本的にはまとめて書くことをおすすめします。
ぶたさん
constを使うときは、変数宣言と代入をまとめて書かないと構文エラーになります。
エラーになる書き方
const a; // ❌(変数宣言のみ書くとエラー)
const a;
a = 1; // ❌(変数宣言と代入を分けて書くとエラー)
正しい書き方
const a = 1; // ✅(変数宣言と代入をまとめて書くとOK)
2. let / var / const の違い

ここでは、3種類ある変数宣言「var / let / const」の違いについて詳しく解説しています。
バージョン

var / let / const」はバージョンが異なります。| 変数宣言 | 公開日 | バージョン |
|---|---|---|
var |
1997年 | ES1 |
let |
2015年 | ES6 |
const |
2015年 | ES6 |
バージョンとは?
JavaScriptができた当初は、ブラウザによってJavaScriptの動きがバラバラだったため開発が大変でした。
そこで「どのブラウザでも同じように動くようにしよう」と決められたルールが「ECMAScript(エクマスクリプト)」です。
JavaScriptはこのルール基づいて作られているため、バージョンが新しくなるたびに「ES5」「ES6」という感じで名前がつけられます。
■新しいバージョン名の表記
「ECMAScript 2016」
「ECMAScript 2017」
「ECMAScript 2018」
各変数宣言のバージョン詳細
varは、バージョンES1からES5まで標準で使われていた変数宣言です。
現在でも使うことはできますが、バグの原因になるなど問題が多いのであまりおすすめできません。
varを使わなければなりませんでした。
しかし、現在ではほとんどのブラウザがES6に対応していますのでvarを使う必要はありません。
let / constは、バージョンES6から導入された新しい変数宣言です。
varと違い予測できない動作やバグが起こりにくいため、安全で読みやすいコードを書くことができるというメリットがあります。
letとconstのみを使うことをおすすめします。
ぶたさん
再宣言

var / let/ const」の再宣言についてです。| 変数宣言 | 再宣言 |
|---|---|
var |
◯ |
let |
✕ |
const |
✕ |
再宣言とは?
| 宣言 | 「◯◯という名前の変数(箱)を作る」とプログラムに伝えること |
|---|---|
| 再宣言 | 「同じ名前を使って再び変数(箱)を作り直す」とプログラムに伝えること |
再宣言の例
var a = 1; // 1回目の宣言
var a = 2; // 2回目の宣言(再宣言)
var a = 1;
変数宣言キーワード「var」を使って「a」という名前の箱を作るとプログラムに伝え、その箱の中に「1」というデータを入れるvar a = 2;
変数宣言キーワード「var」を使って「a」という名前の箱を作り直すとプログラムに伝え、その中に「2」というデータを入れる
| コード | 分類 | 説明 |
|---|---|---|
var |
変数宣言キーワード | 「中身を変えられる箱を作ります」という宣言 |
a |
変数名 | 箱の名前 |
1 , 2 |
変数値 | 箱(a)の中に入れるもの |
= |
代入演算子 | 右のものを左に入れる |
; |
区切り記号 | 文末につける区切り |
ノーノちゃん
varで再宣言した場合、あとから宣言した変数のみが残るようになっています。
ぶたさん
ぶたさん
再宣言した場合の例
varは再宣言できます。
実際に再宣言してプログラムを実行すると次のような結果になります。
var a = 1; // 1回目の宣言
var a = 2; // 2回目の宣言(再宣言)
console.log(a); //コンソールに実行結果を表示
2
varで再宣言すると、はじめに宣言した変数(箱)がすべて削除されてしまいます。
ぶたさん
letは再宣言ができません。
実際に再宣言してプログラムを実行すると次のような結果になります。
let a = 1; // 1回目の宣言
let a = 2; // 2回目の宣言(再宣言)
console.log(a); //コンソールに実行結果を表示
Uncaught SyntaxError SyntaxError: Identifier 'a' has already been declared
letは再宣言できないため、構文エラー(シンタックス・エラー)のメッセージが表示されます。
ぶたさん
constも再宣言ができません。
実際に再宣言してプログラムを実行すると次のような結果になります。
const a = 1; // 1回目の宣言
const a = 2; // 2回目の宣言(再宣言)
console.log(a); //コンソールに実行結果を表示
Uncaught SyntaxError SyntaxError: Identifier 'a' has already been declared
constは再宣言できないため、構文エラー(シンタックス・エラー)のメッセージが表示されます。
ぶたさん
再代入

var / let / const」の再代入についてです。| 変数宣言 | 再代入 |
|---|---|
var |
◯ |
let |
◯ |
const |
✕ |
再代入とは?
| 代入 | 変数(箱)にデータを入れること |
|---|---|
| 再代入 | 変数(箱)にデータを入れたあとに、別の新しいデータを入れて上書きすること |
再代入の例
var a = 1; // 1回目の代入
a = 2; // 2回目の代入(再代入)
const a = 1;
変数宣言キーワード「var」を使って「a」という名前の箱を作ると宣言し、その中にデータ「1」を入れるa = 2;
「a」という名前の箱の中のデータ「1」をデータ「2」に上書き
| コード | 分類 | 説明 |
|---|---|---|
var |
変数宣言キーワード | 「中身を変えられる箱を作ります」という宣言 |
a |
変数名 | 箱の名前 |
1 , 2 |
変数値 | 箱(a)の中に入れるもの |
= |
代入演算子 | 右のものを左に入れる |
; |
区切り記号 | 文末につける区切り |
ノーノちゃん
ぶたさん
再代入した場合の例
varは再代入ができます。
実際に再代入してプログラムを実行すると次のような結果になります。
var a = 1; // 1回目の代入
a = 2; // 2回目の代入(再代入)
console.log(a); //コンソールに実行結果を表示
2
varで再代入すると、はじめに変数(箱)の中に入れたデータがすべて削除されます。そして最後に入れたデータのみが残ります。
ぶたさん
letは再代入ができます。
実際に再代入してプログラムを実行すると次のような結果になります。
let a = 1; // 1回目の代入
a = 2; // 2回目の代入(再代入)
console.log(a); //コンソールに実行結果を表示
2
letで再代入すると、はじめに変数(箱)の中に入れたデータがすべて削除されます。そして最後に入れたデータのみが残ります。
ぶたさん
constは再代入できません。
実際に再代入してプログラムを実行すると次のような結果になります。
const a = 1; // 1回目の代入
a = 2; // 2回目の代入(再代入)
console.log(a); //コンソールに実行結果を表示
Uncaught TypeError TypeError: Assignment to constant variable.
constは再代入できませんので、エラーメッセージが表示されます。
ぶたさん
スコープ ※中級者向け

var / let / const」のスコープ(有効範囲)についてです。JavaScriptに慣れてきたら、もう一度戻ってきて読んでみてくださいね。
| 変数宣言 キーワード |
スコープ(有効範囲) |
|---|---|
var |
・グローバルスコープ ・関数スコープ |
let |
・グローバルスコープ ・ブロックスコープ |
const |
・グローバルスコープ ・ブロックスコープ |
スコープとは?
スコープとは、宣言された変数や関数の有効範囲(アクセスできる範囲)を決めるものです。
JavaScriptでは、変数や関数をどこで宣言したかによって、その変数や関数にアクセスできる範囲が決まります。
具体的にはスコープ内で宣言された変数や関数は、そのスコープ内でのみアクセスでき、スコープ外からアクセスできない仕組みになっています。
ぶたさん
各スコープの詳細
グローバルスコープとは、関数や{}ブロックの外で宣言された変数のスコープのことを指します。
このスコープで宣言された変数は「グローバル変数」と呼ばれ、コード内のどこからでもアクセスできるという特徴があります。
ぶたさん
let a = 1; // グローバルスコープで変数「a」宣言
// 関数「test」を宣言
function test() {
console.log(a); // 関数内から変数「a」にアクセス
}
test(); // 関数「test」を呼び出す
1
このように、グローバルスコープで宣言された変数aは、関数内からでもアクセスすることができてしまいます。
そのため、意図しない上書きなどエラーの原因になることが多いため、基本的には使わないようにしましょう。
このスコープで宣言された変数は、その関数の中でしか使うことができず、外からはアクセスできないという特徴があります。
// 関数「test」を宣言
function test() {
let a = 1; // 関数内で変数「a」宣言
}
console.log(a); // 関数外から関数内で宣言された変数「a」にアクセス
Uncaught ReferenceError ReferenceError: a is not defined
このように、関数内で宣言された変数aは、その関数外からはアクセスできません。
ブロックスコープとは、{}ブロック内で宣言された変数のスコープのことを指します。
このスコープで宣言された変数は、その{}ブロック内でしか使うことができず、外からはアクセスできません。
if (true) {
let a = 1; // ブロックスコープで変数「c」宣言
}
console.log(a); // エラー:cは定義されていない
Uncaught ReferenceError ReferenceError: a is not defined
このように、{}ブロック内で宣言された変数を、ブロック外でアクセスしようとするとエラーになります。
{}ブロック内で宣言された変数cは、{}ブロック外からアクセスすることができません。
そのため、変数が使える範囲が限定されるので安全に扱うことができるというメリットがあります。
巻き上げ ※中級者向け

var / let / const」の巻き上げ(ホスティング)についてです。JavaScriptに慣れてきたら、もう一度戻ってきて読んでみてくださいね。
| 変数宣言 | 巻き上げ |
|---|---|
var |
エラーが表示されない (undefinedとだけ表示される) |
let |
Referenceエラーが表示される |
const |
Referenceエラーが表示される |
巻き上げとは?
「巻き上げ(ホスティング)」は、あとに書いていたはずの変数や関数の「宣言」が、実行前に先に読み込まれることです。
JavaScriptは通常、コードが書かれた順番通りにコードを実行していきますが、巻き上げされると順番関係なく宣言が先に読み込みされます。
この現象が巻き上げと呼ばれています。
ノーノちゃん
ぶたさん
巻き上げの例
JavaScriptは通常、次のように変数宣言をしてから出力命令を書きますよね。
var a = 1; //変数宣言
console.log(a); //出力命令
1
実行結果は1になりますよね。
しかし、先に出力命令を書いて、あとで変数宣言をした場合はどうなるでしょうか?
console.log(a); //出力命令
var a = 1; //変数宣言
undefined
実行結果は「undefined(まだ値が入っていない)」になります。
通常、変数宣言されていないのに出力命令をするとエラーになるはずですが、なぜこのような結果になるのか気になりますよね。
それはJavaScriptが次のようにコードを実行する前に、宣言を先に読み取る仕組みになっているからです。
var a; // 宣言
console.log(a); // 出力命令
a = 1; // 代入
このように宣言だけが先に読み取り、処理されてしまう現象を巻き上げといいます。
巻き上げされると以下のような問題が起こります。
- バグに気づきにくい
(存在しないはずの変数がundefinedとして動作してしまい、エラーが出ないので問題に気づきにくい。) - 変数の位置と実行結果がズレる
(コード上はあとで宣言されているのに、実行時には先に宣言されているかのように扱われるため意図しない動作になる) - コードが読みづらくなる
(見た目と動きが一致しないため、特にチーム開発や後で見直すときに「なんでこうなるの?」と分かりにくくなる。)
このようにバグや読みづらさの原因となるため、巻き上げが起こらないように正しいコードを書くことが重要です。
ノーノちゃん
varを使わないことです。letとconstは、宣言前に変数を使おうとするとエラーになるのでバグに気づきやすくなります。
ぶたさん
各宣言で巻き上げの例
console.log(a);
var a = 1;
undefined
varで巻き上げられた場合「undefined」とだけ表示されます。
これはエラーメッセージではなく「宣言された変数にデータが入っていない」というメッセージです。
このようにvarで巻き上げが起きた場合、エラーが出ないため問題に気づきにくいというデメリットがあります。
console.log(a);
let a = 1;
Uncaught ReferenceError ReferenceError: Cannot access 'a' before initialization
let / constで巻き上げられた場合「Uncaught ReferenceError」とだけ表示されます。
これは「存在しない変数a、または使える状態になっていない変数aにアクセスしようとした」というエラーメッセージです。
このようにlet / constで巻き上げが起きた場合、どの変数に問題があるのかエラーで知らせてくれるのでバグに気づきやすくなります。
3. let / var / const 使い分け

ここでは変数宣言キーワード「var / let / const」の使い分け方について解説しています。
初心者の方だけでなく、よく分からずに使っているという方も
const(最優先で使う)
| 変数宣言キーワード【変数宣言キーワード】 プログラムに「どんな変数(箱)を作るのか」を伝えるためのもの |
const |
|---|---|
| バージョン【バージョン】 ECMAScriptのバージョン |
ES6(2015年) |
| 再宣言【再宣言】 一度作った変数(箱)と、同じ名前の変数(箱)を作ること |
✕ |
| 再代入【再代入】 一度データを入れた変数(箱)に、新しいデータを入れること |
✕ |
| スコープ【スコープ】 変数が使える範囲 |
・グローバルスコープ ・ブロックスコープ |
| 巻き上げ【巻き上げ】 変数宣言だけが先に処理される現象 |
エラーが表示される |
基本的に変数宣言のキーワードはconstを使いましょう。
なぜならconstは変数(箱)の中身が変わらないので、意図していないデータの上書きを防ぐことができるからです。
プログラミングでは時間が経ってから自分の書いたコードを見返したとき「これって何のための変数だったっけ?」と迷うことがあります。
そんなときconstで宣言されていれば「ここは変数(箱)の中身は変わらないんだな」とコードの意図を把握しやすくなります。
このように、保守性や読みやすさの面からもconstを使うことをおすすめします。
constはブロックごとに変数の管理ができるため、安全で読みやすいコードを書くことができるメリットもあります。
ぶたさん
let(必要なときだけ使う)
| 変数宣言キーワード【変数宣言キーワード】 プログラムに「どんな変数(箱)を作るのか」を伝えるためのもの |
let |
|---|---|
| バージョン【バージョン】 ECMAScriptのバージョン |
ES6(2015年) |
| 再宣言【再宣言】 一度作った変数(箱)と、同じ名前の変数(箱)を作ること |
✕ |
| 再代入【再代入】 一度データを入れた変数(箱)に、新しいデータを入れること |
◯ |
| スコープ【スコープ】 変数が使える範囲 |
・グローバルスコープ ・ブロックスコープ |
| 巻き上げ【巻き上げ】 変数宣言だけが先に処理される現象 |
エラーが表示される |
変数宣言キーワードletは「変数(箱)の中身を変更される、またはあとで変更したい」という場合のみ使いましょう。
具体的にはループ処理(繰り返し処理)などで、変数の中身が変更されるときに使います。
たとえば、次のように変数iの中身を1→2→3→4と変化させながら繰り返し処理(ループ)していくケースです。
for (let i = 1; i < 5; i++) {
console.log(i);
}
| コード | 分類 | 意味 |
|---|---|---|
for() |
ループ処理 | 指定した条件で繰り返し処理をさせる命令 |
let |
変数宣言 キーワード |
「中身を変えられる箱を作ります」という宣言 |
i |
変数名 | 作成する箱の名前 (ループ処理の際に使われる変数名) |
= |
代入演算子 | 右のものを左に入れる |
1 |
数値 | ループのカウントをスタートする値 |
; |
区切り記号 | 文末につける区切り |
i < 5 |
条件式 | 「iが5以下の間はループを繰り返す」という条件 |
i++ |
インクリメント (増加処理) |
毎回ループが1回終わるたびにiの値を1増やす。 |
() |
丸括弧 | 処理したい部分を囲む |
{} |
波括弧 | 処理したい部分を囲む |
console.log() |
出力命令 | ()の中身をコンソールに表示 |
こういった場合constを使うとiの中身が変更できないため、エラーになってしまいます。
したがって、変数(箱)の中身が変更されるケースのみletを使いましょう。
var(基本的に使わない)
| 変数宣言【変数宣言】 プログラムに「どんな変数(箱)を作るのか」を伝えるためのもの |
var |
|---|---|
| バージョン【バージョン】 ECMAScriptのバージョン |
ES1(1997年) |
| 再宣言【再宣言】 一度作った変数(箱)と、同じ名前の変数(箱)を作ること |
◯ |
| 再代入【再代入】 一度データを入れた変数(箱)に、新しいデータを入れること |
◯ |
| スコープ【スコープ】 変数が使える範囲 |
・グローバルスコープ ・関数スコープ |
| 巻き上げ【巻き上げ】 変数宣言だけが先に処理される現象 |
undefined(未定義)が表示される |
基本的にvarは使わないです。
なぜならvarは何度でも再宣言できるため、意図しない変数の上書きによるバグが起こりやすいからです。
また、関数の中でしかスコープが区切られないため、ブロック{}内で宣言しても、外からアクセスできてしまうという欠点があります。
このようにデメリットが非常に多いのでvarを使うことはおすすめできません。
varを使わないですが、昔のコードで出てくるので知識として理解しておきましょう。
ぶたさん
4. よくある質問

ここでは変数宣言「let / var / const」についてのよくある質問をご紹介しています。
変数宣言が必要な理由は?
しかし、変数宣言が必要な理由は、宣言することでエラーを防いだり、プログラムがデータを正しく使えるようにするためです。
たとえば、いきなり「りんごを冷蔵庫に入れておいて」と言われても、その場所に冷蔵庫がなかったら困ってしまいますよね。
プログラムも同じで、先に「冷蔵庫(変数)」の存在を知らせておかないと「りんご(データ)」をどこに入れればいいのか分かりません。
つまり、「この名前の変数(箱)にデータを入れるよ」とプログラムに伝えるために変数宣言は必要です。
ノーノちゃん
ぶたさん
ぶたさん
一方、特定の場所だけで使える変数を「ローカル変数」といいます。
letが使えない
letが使えない場合は次のいずれかの原因が考えられます。
letが使えない最も多い理由が構文ミスです。
たとえば、下記のように間違った書き方をしていると、JavaScriptは正しく読み取れず構文エラーになります。
lot x = 10; // ← 「let」が「lot」になっている
console.log(x)
Uncaught SyntaxError SyntaxError: Unexpected identifier 'x'
ぶたさん
letが使えないもうひとつの原因が、ブロックスコープの問題です。
ブロックスコープとは、変数や関数が使える範囲のことで、かんたんに言うと{}内のことです。
たとえば、下記のように同じブロック({}で囲まれた範囲)内で、同じ名前の変数をletで再宣言しようとするとエラーになります。
{
let x = 1;
let x = 2; // エラー:xはすでにこのブロック内で宣言されている
}
これはletが同じスコープ内での再宣言が許されていないためです。
変数を上書きしたい場合は、下記のように再宣言ではなく再代入を使う必要があります。
{
let x = 1;
x = 2; // これはOK(再代入)
}
letは使わない?非推奨?
結論から言うとletは非推奨ではありません。
これは再代入があるときに使う変数宣言ですので、使ってもまったく問題ありません。
ただし、プログラマーの中には「再代入しない変数はすべてconstで宣言すべき」という意見があります。
実際にエンジニアの現場でも、意図しない再代入を防ぐためにconstを使われていることが多いです。
個人的にもletでなければいけないケース以外はconstを使うことをおすすめします。
【JSの豆知識】
JSの変数宣言はvar、let、constとあるが、ほとんどconstしか使わない。
現場のソースコードも9割const。
理由は意図しない値の再代入を防ぐため。
気軽にvarやletを書くのは避けよう。#プログラミング初心者#駆け出しエンジニアと繋がりたい— よすけ (@yosuke_midman) March 11, 2022
varは使わない?
結論から言うとvarを使うことはおすすめしません。
なぜならvarには次のようなデメリットがあるからです。
- 何度も再宣言できる
(同じ変数名で何度も宣言できるため、意図しない上書きやバグにつながりやすい。) - 巻き上げされた際エラーが出ない
(問題の箇所が分からないので、自力で探さないといけない) - ブロックスコープがない
({}の内側で宣言しても、その外からアクセスできてしまう)
このようにバグの原因になる可能性がありますので、現在では安全性の高いletとconstを使うことが推奨されています。
ノーノちゃん
varを使ってる人よく見かけるよvarに慣れてるからです。これから学ぶ方はletやconstを使うことをおすすめします。
ぶたさん
5. まとめ

結論としましては、変数宣言キーワードはconstを使いましょう。
constは変数の中身が変わらないのでバグを防ぎやすく、コードの意図が明確にできるメリットがあります。
一方で、変数の中身をあとで変える、またはループ処理などで変数の中身が変わる場合はletを使いましょう。
なお、varは再宣言ができたり、スコープの扱いが特殊だったり、バグの原因になりやすいので使わないようにしましょう。
- 変数宣言はどんな変数を作るかをプログラムに伝えるためのもの
- 変数宣言キーワードは
var/let/constの3種類ある constを優先的に使うletは必要なときにだけ使うvarは基本的には使わない


