Amazon 数量限定タイムセール開催中

【ES6】JavaScript:let / var / constの違いは?使い方を解説!

【JavaScript (ES6)】let / var / constの違いは?使い方を解説!

JavaScriptを学び始めたときに混乱するのが「変数宣言」ですよね。

let / var / constの3種類の変数宣言キーワードがあるけど、どれを使えばいいの?」と悩んでいる方が多いのではないでしょうか。

このページでは、各変数宣言キーワードの違いや、使い方などを初心者の方にも分かりやすく解説しています。

違いが分からないけど、なんとなく使っているという方も、ぜひ参考にしてみてくださいね。

ノーノちゃん

JavaScriptの講座サイトには、変数宣言キーワードはvarを使わずにletconstを使うって書いてあったよ。
そうですね。これからJavaScriptをはじめる方はletconstを使うことをおすすめします。それについても書いていますのでよければチェックしてみてください。

ぶたさん

1. 変数宣言とは?

変数宣言とは?

まずはじめに変数宣言について解説します。

これを理解していないと、次に進んでも混乱してしまいますのでしっかり把握しておきましょう。

どんな変数を作るかを伝えるもの

どんな変数を作るかを伝えるもの
ここでは変数宣言について解説します。

変数宣言とは、「◯◯という名前の変数(箱)を作ります」とプログラムに伝えるためのものです。

たとえば、学校の授業中にいきなり手を上げた場合、なぜ手を上げたのか伝えないと先生は困ってしまいますよね。

  • 「質問があります」
  • 「トイレに行きたいです」
  • 「体調が悪いので保健室に行きたいです」

このように手を上げた理由を伝えることで、先生は適切に対応することができます。

JavaScriptも同じで、プログラムが適切に対応できるように、あらかじめ変数(箱)を作ることを伝えておく必要があります。

そのために行うのが変数宣言です。

ノーノちゃん

変数宣言はどうやってやるの?
「変数宣言キーワード」を使って宣言します。

ぶたさん

変数宣言キーワードとは?

変数宣言キーワードとは?
ここでは変数宣言キーワードについて解説します。

変数宣言キーワードとは、プログラムに「こういう種類の変数(箱)を作ります」と伝えるためのものです。

JavaScriptには次のように3種類の変数宣言キーワードがあります。

変数宣言
キーワード
特徴
var ・何度も同じ名前で変数(箱)を作れる
・中身はあとから自由に変えられる
let ・同じ名前の変数(箱)は一度しか作れない
・中身はあとから自由に変えられる
const ・同じ名前の変数(箱)は一度しか作れない
・一度中身を入れたら変えられない
変数宣言キーワードの違いについては「2. let / var / const の違い」をご覧ください。

ぶたさん

変数宣言の使い方とは?

変数宣言の使い方
ここでは変数宣言のやり方を解説します。

変数宣言

変数宣言のやり方は、まず変数宣言キーワードを書き、そのあとに変数名(箱の名前)を書きます。

js
コピー 拡大
let a;
コード 分類 意味
let 変数宣言キーワード 「中身を変えられる箱を作ります」という宣言
a 変数名 作成する箱の名前
; 区切り記号 文末につける区切り

 
変数宣言キーワードletを使って「aという名前の変数(箱)を作ります」とプログラムに伝えています。

ノーノちゃん

変数(箱)の中にどうやってデータを入れるの?
変数宣言したあとに「代入」という方法を使ってデータを入れます。

ぶたさん

代入

代入のやり方は、まずはじめに変数宣言を書き、その下に「変数 = 変数に入れたい値」を書きます。

js
コピー 拡大
let a; //変数宣言
a = 1; //代入
コード 分類 意味
let 変数宣言キーワード 「中身を変えられる箱を作ります」という宣言
a 変数名 作成する箱の名前
= 代入演算子 右のものを左に入れる
1 変数値 箱(a)の中に入れるデータ
; 区切り記号 文末につける区切り

 
まずはじめに、変数宣言キーワードletを使って「aという名前の変数(箱)を作ります」とプログラムに伝えています。

そのあと、先ほど作った「aという箱の中に、1というデータを入れますよ」と伝えています。

ノーノちゃん

この変数宣言と代入はまとめて書けないの?
定義(初期化)というまとめて書く方法があります。

ぶたさん

定義(初期化)

js
コピー 拡大
let a = 1; //変数宣言 + 代入
コード 分類 意味
let 変数宣言キーワード 「中身を変えられる箱を作ります」という宣言
a 変数名 作成する箱の名前
= 代入演算子 右のものを左に入れる
1 変数値 箱(a)の中に入れるデータ
; 区切り記号 文末につける区切り

これは変数宣言と代入をまとめて書いた例です。

このように変数宣言と代入を同時に行うことを「定義(初期化)」といいます。

一般的にコードを書くときは、行数を減らして読みやすくするために、変数宣言と代入をまとめて書くことが多いです。

constの場合は分けて書くとエラーになりますので、基本的にはまとめて書くことをおすすめします。

ぶたさん

変数宣言キーワードconstを使うときは、変数宣言と代入をまとめて書かないと構文エラーになります。

エラーになる書き方
js
コピー 拡大
const a; // ❌(変数宣言のみ書くとエラー)
js
コピー 拡大
const a;
a = 1; // ❌(変数宣言と代入を分けて書くとエラー)
正しい書き方
js
コピー 拡大
const a = 1; // ✅(変数宣言と代入をまとめて書くとOK)

2. let / var / const の違い

let / var / const の違い

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

バージョン

「var / let / const」はJavaScriptのバージョンが異なる
var / let / const」はバージョンが異なります。
変数宣言 公開日 バージョン
var 1997年 ES1
let 2015年 ES6
const 2015年 ES6

バージョンとは?

「ES」は「ECMAScript(エクマスクリプト)」の略です。

JavaScriptができた当初は、ブラウザによってJavaScriptの動きがバラバラだったため開発が大変でした。

そこで「どのブラウザでも同じように動くようにしよう」と決められたルールが「ECMAScript(エクマスクリプト)」です。

JavaScriptはこのルール基づいて作られているため、バージョンが新しくなるたびに「ES5」「ES6」という感じで名前がつけられます。

補足
ES6以降バージョン名は年号で表すようになっています。
 
■新しいバージョン名の表記
「ECMAScript 2016」
「ECMAScript 2017」
「ECMAScript 2018」

各変数宣言のバージョン詳細

varは、バージョンES1からES5まで標準で使われていた変数宣言です。

現在でも使うことはできますが、バグの原因になるなど問題が多いのであまりおすすめできません。

varは使わなくてもいい?
以前はES6非対応のブラウザ(Internet Explorerなど)があったため、varを使わなければなりませんでした。

しかし、現在ではほとんどのブラウザがES6に対応していますのでvarを使う必要はありません。

let / constは、バージョンES6から導入された新しい変数宣言です。

varと違い予測できない動作やバグが起こりにくいため、安全で読みやすいコードを書くことができるというメリットがあります。

これからJavaScriptを学びはじめるという方はletconstのみを使うことをおすすめします。

ぶたさん

再宣言

let / var / const 再宣言の違い
var / let/ const」の再宣言についてです。
変数宣言 再宣言
var
let
const

再宣言とは?

宣言 「◯◯という名前の変数(箱)を作る」とプログラムに伝えること
再宣言 「同じ名前を使って再び変数(箱)を作り直す」とプログラムに伝えること
再宣言の例
js
コピー 拡大
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)の中に入れるもの
= 代入演算子 右のものを左に入れる
; 区切り記号 文末につける区切り

ノーノちゃん

再宣言は1回目の宣言が、2回目の宣言に上書きされるの?
上書きされます。varで再宣言した場合、あとから宣言した変数のみが残るようになっています。

ぶたさん

そのため、うっかり再宣言してしまい、意図しない上書きが起こるという危険性があります。

ぶたさん

再宣言した場合の例

varは再宣言できます。

実際に再宣言してプログラムを実行すると次のような結果になります。

js
コピー 拡大
var a = 1; // 1回目の宣言
var a = 2; // 2回目の宣言(再宣言)

console.log(a); //コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
2
varで再宣言すると、はじめに宣言した変数(箱)がすべて削除されてしまいます。

ぶたさん

letは再宣言ができません。

実際に再宣言してプログラムを実行すると次のような結果になります。

js
コピー 拡大
let a = 1; // 1回目の宣言
let a = 2; // 2回目の宣言(再宣言)

console.log(a);	//コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
Uncaught SyntaxError SyntaxError: Identifier 'a' has already been declared
letは再宣言できないため、構文エラー(シンタックス・エラー)のメッセージが表示されます。

ぶたさん

constも再宣言ができません。

実際に再宣言してプログラムを実行すると次のような結果になります。

js
コピー 拡大
const a = 1; // 1回目の宣言
const a = 2; // 2回目の宣言(再宣言)

console.log(a); //コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
Uncaught SyntaxError SyntaxError: Identifier 'a' has already been declared
constは再宣言できないため、構文エラー(シンタックス・エラー)のメッセージが表示されます。

ぶたさん

再代入

let / var / const 再代入の違い
var / let / const」の再代入についてです。
変数宣言 再代入
var
let
const

再代入とは?

代入 変数(箱)にデータを入れること
再代入 変数(箱)にデータを入れたあとに、別の新しいデータを入れて上書きすること
再代入の例
js
コピー 拡大
var a = 1;	// 1回目の代入
a = 2;		// 2回目の代入(再代入)
コードの流れ解説
  • const a = 1;
    変数宣言キーワード「var」を使って「a」という名前の箱を作ると宣言し、その中にデータ「1」を入れる
  • a = 2;
    「a」という名前の箱の中のデータ「1」をデータ「2」に上書き
コード 分類 説明
var 変数宣言キーワード 「中身を変えられる箱を作ります」という宣言
a 変数名 箱の名前
1 , 2 変数値 箱(a)の中に入れるもの
= 代入演算子 右のものを左に入れる
; 区切り記号 文末につける区切り

ノーノちゃん

再代入は、はじめに「お菓子箱にチョコレート入れておいて」と言って、あとから「やっぱりチョコレートはやめてクッキーを入れておいて」みたいな感じ?
イメージとしては近いです。細かく言えば、再代入は前のデータが削除されるので「チョコレートを捨てて、代わりにクッキーを入れる」が正しいです。

ぶたさん

再代入した場合の例

varは再代入ができます。

実際に再代入してプログラムを実行すると次のような結果になります。

js
コピー 拡大
var a = 1;	// 1回目の代入
a = 2;		// 2回目の代入(再代入)

console.log(a);	//コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
2
varで再代入すると、はじめに変数(箱)の中に入れたデータがすべて削除されます。そして最後に入れたデータのみが残ります。

ぶたさん

letは再代入ができます。

実際に再代入してプログラムを実行すると次のような結果になります。

js
コピー 拡大
let a = 1;	// 1回目の代入
a = 2;		// 2回目の代入(再代入)

console.log(a);	//コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
2
letで再代入すると、はじめに変数(箱)の中に入れたデータがすべて削除されます。そして最後に入れたデータのみが残ります。

ぶたさん

constは再代入できません。

実際に再代入してプログラムを実行すると次のような結果になります。

js
コピー 拡大
const a = 1;		// 1回目の代入
a = 2;			// 2回目の代入(再代入)

console.log(a);	//コンソールに実行結果を表示
コンソール(実行結果)
コピー 拡大
Uncaught TypeError TypeError: Assignment to constant variable.
constは再代入できませんので、エラーメッセージが表示されます。

ぶたさん

スコープ ※中級者向け

let / var / const  スコープの違い
var / let / const」のスコープ(有効範囲)についてです。
注意
この項目は少し難しい内容が含まれていますので、初心者の方は読み飛ばしてください。

JavaScriptに慣れてきたら、もう一度戻ってきて読んでみてくださいね。

変数宣言
キーワード
スコープ(有効範囲)
var ・グローバルスコープ
・関数スコープ
let ・グローバルスコープ
・ブロックスコープ
const ・グローバルスコープ
・ブロックスコープ

スコープとは?

スコープとは、宣言された変数や関数の有効範囲(アクセスできる範囲)を決めるものです。

JavaScriptでは、変数や関数をどこで宣言したかによって、その変数や関数にアクセスできる範囲が決まります。

具体的にはスコープ内で宣言された変数や関数は、そのスコープ内でのみアクセスでき、スコープ外からアクセスできない仕組みになっています。

スコープは商品券が使える場所みたいなものです。商店街(関数)で発行された券(変数)は商店街の中(関数内)でしか使えないみたいな感じです。

ぶたさん

各スコープの詳細

グローバルスコープとは、関数や{}ブロックの外で宣言された変数のスコープのことを指します。

このスコープで宣言された変数は「グローバル変数」と呼ばれ、コード内のどこからでもアクセスできるという特徴があります。

次のようにグローバルスコープで宣言した変数は、関数内からでもアクセスすることができます。

ぶたさん

js
コピー 拡大
let a = 1; // グローバルスコープで変数「a」宣言

// 関数「test」を宣言
function test() { 
  console.log(a); // 関数内から変数「a」にアクセス
}

test(); // 関数「test」を呼び出す
コンソール(実行結果)
コピー 拡大
1

このように、グローバルスコープで宣言された変数aは、関数内からでもアクセスすることができてしまいます。

そのため、意図しない上書きなどエラーの原因になることが多いため、基本的には使わないようにしましょう。

関数スコープとは、関数内で宣言された変数のスコープのことを指します。

このスコープで宣言された変数は、その関数の中でしか使うことができず、外からはアクセスできないという特徴があります。

js
コピー 拡大
// 関数「test」を宣言
function test() {
  let a = 1; // 関数内で変数「a」宣言
}

console.log(a); // 関数外から関数内で宣言された変数「a」にアクセス
コンソール(実行結果)
コピー 拡大
Uncaught ReferenceError ReferenceError: a is not defined

このように、関数内で宣言された変数aは、その関数外からはアクセスできません。

ブロックスコープとは、{}ブロック内で宣言された変数のスコープのことを指します。

このスコープで宣言された変数は、その{}ブロック内でしか使うことができず、外からはアクセスできません。

js
コピー 拡大
if (true) {
  let a = 1; // ブロックスコープで変数「c」宣言
}

console.log(a); // エラー:cは定義されていない
コンソール(実行結果)
コピー 拡大
Uncaught ReferenceError ReferenceError: a is not defined

このように、{}ブロック内で宣言された変数を、ブロック外でアクセスしようとするとエラーになります。

{}ブロック内で宣言された変数cは、{}ブロック外からアクセスすることができません。

そのため、変数が使える範囲が限定されるので安全に扱うことができるというメリットがあります。

巻き上げ ※中級者向け

let / var / const  巻き上げ(ホスティング)の違い
var / let / const」の巻き上げ(ホスティング)についてです。
注意
この項目は少し難しい内容が含まれていますので、初心者の方は読み飛ばしてください。

JavaScriptに慣れてきたら、もう一度戻ってきて読んでみてくださいね。

変数宣言 巻き上げ
var エラーが表示されない
(undefinedとだけ表示される)
let Referenceエラーが表示される
const Referenceエラーが表示される

巻き上げとは?

「巻き上げ(ホスティング)」は、あとに書いていたはずの変数や関数の「宣言」が、実行前に先に読み込まれることです。

JavaScriptは通常、コードが書かれた順番通りにコードを実行していきますが、巻き上げされると順番関係なく宣言が先に読み込みされます。

この現象が巻き上げと呼ばれています。

ノーノちゃん

意味がわからないよ…。
こればかりは実際にコードを書いたことがないと理解するのが難しいかもしれません。とりあえず実際の巻き上げの例を見てみましょう。

ぶたさん

巻き上げの例

JavaScriptは通常、次のように変数宣言をしてから出力命令を書きますよね。

js
コピー 拡大
var a = 1; //変数宣言
console.log(a); //出力命令
コンソール(実行結果)
コピー 拡大
1

実行結果は1になりますよね。

しかし、先に出力命令を書いて、あとで変数宣言をした場合はどうなるでしょうか?

js
コピー 拡大
console.log(a); //出力命令
var a = 1; //変数宣言
コンソール(実行結果)
コピー 拡大
undefined

実行結果は「undefined(まだ値が入っていない)」になります。

通常、変数宣言されていないのに出力命令をするとエラーになるはずですが、なぜこのような結果になるのか気になりますよね。

それはJavaScriptが次のようにコードを実行する前に、宣言を先に読み取る仕組みになっているからです。

js
コピー 拡大
var a; // 宣言
console.log(a); // 出力命令
a = 1; // 代入

このように宣言だけが先に読み取り、処理されてしまう現象を巻き上げといいます。

巻き上げされると以下のような問題が起こります。

  • バグに気づきにくい
    (存在しないはずの変数がundefinedとして動作してしまい、エラーが出ないので問題に気づきにくい。)
  • 変数の位置と実行結果がズレる
    (コード上はあとで宣言されているのに、実行時には先に宣言されているかのように扱われるため意図しない動作になる)
  • コードが読みづらくなる
    (見た目と動きが一致しないため、特にチーム開発や後で見直すときに「なんでこうなるの?」と分かりにくくなる。)

このようにバグや読みづらさの原因となるため、巻き上げが起こらないように正しいコードを書くことが重要です。

ノーノちゃん

巻き上げによるバグを防ぐ方法は他にないの?
結論を言うとvarを使わないことです。letconstは、宣言前に変数を使おうとするとエラーになるのでバグに気づきやすくなります。

ぶたさん

各宣言で巻き上げの例

js
コピー 拡大
console.log(a);
var a = 1;
コンソール(実行結果)
コピー 拡大
undefined

varで巻き上げられた場合「undefined」とだけ表示されます。

これはエラーメッセージではなく「宣言された変数にデータが入っていない」というメッセージです。

このようにvarで巻き上げが起きた場合、エラーが出ないため問題に気づきにくいというデメリットがあります。

js
コピー 拡大
console.log(a);
let a = 1;
コンソール(実行結果)
コピー 拡大
Uncaught ReferenceError ReferenceError: Cannot access 'a' before initialization

let / constで巻き上げられた場合「Uncaught ReferenceError」とだけ表示されます。

これは「存在しない変数a、または使える状態になっていない変数aにアクセスしようとした」というエラーメッセージです。

このようにlet / constで巻き上げが起きた場合、どの変数に問題があるのかエラーで知らせてくれるのでバグに気づきやすくなります。

4. let / var / const 使い分け

変数宣言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と変化させながら繰り返し処理(ループ)していくケースです。

js
コピー 拡大
for (let i = 1; i < 5; i++) {
  console.log(i);
}
コード 分類 意味
for() ループ処理 指定した条件で繰り返し処理をさせる命令
let 変数宣言
キーワード
「中身を変えられる箱を作ります」という宣言
i 変数名 作成する箱の名前
(ループ処理の際に使われる変数名)
= 代入演算子 右のものを左に入れる
1 数値 ループのカウントをスタートする値
; 区切り記号 文末につける区切り
i < 5 条件式 i5以下の間はループを繰り返す」という条件
i++ インクリメント
(増加処理)
毎回ループが1回終わるたびにiの値を1増やす。
() 丸括弧 処理したい部分を囲む
{} 波括弧 処理したい部分を囲む
console.log() 出力命令 ()の中身をコンソールに表示

こういった場合constを使うとiの中身が変更できないため、エラーになってしまいます。

したがって、変数(箱)の中身が変更されるケースのみletを使いましょう。

var(基本的に使わない)

変数宣言【変数宣言】

プログラムに「どんな変数(箱)を作るのか」を伝えるためのもの

var
バージョン【バージョン】

ECMAScriptのバージョン

ES1(1997年)
再宣言【再宣言】

一度作った変数(箱)と、同じ名前の変数(箱)を作ること

再代入【再代入】

一度データを入れた変数(箱)に、新しいデータを入れること

スコープ【スコープ】

変数が使える範囲

・グローバルスコープ
・関数スコープ
巻き上げ【巻き上げ】

変数宣言だけが先に処理される現象

undefined(未定義)が表示される

 
基本的にvarは使わないです。

なぜならvarは何度でも再宣言できるため、意図しない変数の上書きによるバグが起こりやすいからです。

また、関数の中でしかスコープが区切られないため、ブロック{}内で宣言しても、外からアクセスできてしまうという欠点があります。

このようにデメリットが非常に多いのでvarを使うことはおすすめできません。

現在ではvarを使わないですが、昔のコードで出てくるので知識として理解しておきましょう。

ぶたさん

5. よくある質問

変数宣言「let / var / const」についてのよくある質問

ここでは変数宣言「let / var / const」についてのよくある質問をご紹介しています。

変数宣言が必要な理由は?

しかし、変数宣言が必要な理由は、宣言することでエラーを防いだり、プログラムがデータを正しく使えるようにするためです。

たとえば、いきなり「りんごを冷蔵庫に入れておいて」と言われても、その場所に冷蔵庫がなかったら困ってしまいますよね。

プログラムも同じで、先に「冷蔵庫(変数)」の存在を知らせておかないと「りんご(データ)」をどこに入れればいいのか分かりません。

つまり、「この名前の変数(箱)にデータを入れるよ」とプログラムに伝えるために変数宣言は必要です。

ノーノちゃん

変数宣言しないとどうなるの?
JavaScriptでは宣言しなくても変数にデータを入れることができます。

ぶたさん

しかし、宣言しない場合「グローバル変数」になるため、バグの温床になる危険性があります。

ぶたさん

グローバル変数とは?
「グローバル変数」とは、プログラム内のどこからでも使える変数のことです。

一方、特定の場所だけで使える変数を「ローカル変数」といいます。

letが使えない

letが使えない場合は次のいずれかの原因が考えられます。

letが使えない最も多い理由が構文ミスです。

たとえば、下記のように間違った書き方をしていると、JavaScriptは正しく読み取れず構文エラーになります。

js
コピー 拡大
lot x = 10;  // ← 「let」が「lot」になっている
console.log(x)
コンソール(実行結果)
コピー 拡大
Uncaught SyntaxError SyntaxError: Unexpected identifier 'x'
入力ミスがないか、文法的に間違っていないか確認しましょう。

ぶたさん

letが使えないもうひとつの原因が、ブロックスコープの問題です。

ブロックスコープとは、変数や関数が使える範囲のことで、かんたんに言うと{}内のことです。

たとえば、下記のように同じブロック({}で囲まれた範囲)内で、同じ名前の変数をletで再宣言しようとするとエラーになります。

js
コピー 拡大
{
  let x = 1;
  let x = 2; // エラー:xはすでにこのブロック内で宣言されている
}

これはletが同じスコープ内での再宣言が許されていないためです。

変数を上書きしたい場合は、下記のように再宣言ではなく再代入を使う必要があります。

js
コピー 拡大
{
let x = 1;
x = 2; // これはOK(再代入)
}

letは使わない?非推奨?

結論から言うとletは非推奨ではありません。

これは再代入があるときに使う変数宣言ですので、使ってもまったく問題ありません。

ただし、プログラマーの中には「再代入しない変数はすべてconstで宣言すべき」という意見があります。

実際にエンジニアの現場でも、意図しない再代入を防ぐためにconstを使われていることが多いです。

個人的にもletでなければいけないケース以外はconstを使うことをおすすめします。

varは使わない?

結論から言うとvarを使うことはおすすめしません。

なぜならvarには次のようなデメリットがあるからです。

  • 何度も再宣言できる
    (同じ変数名で何度も宣言できるため、意図しない上書きやバグにつながりやすい。)
  • 巻き上げされた際エラーが出ない
    (問題の箇所が分からないので、自力で探さないといけない)
  • ブロックスコープがない
    ({}の内側で宣言しても、その外からアクセスできてしまう)

このようにバグの原因になる可能性がありますので、現在では安全性の高いletconstを使うことが推奨されています。

ノーノちゃん

今でもvarを使ってる人よく見かけるよ
それは昔からJavaScriptを書いてる方はvarに慣れてるからです。これから学ぶ方はletconstを使うことをおすすめします。

ぶたさん

6. まとめ

JavaScript変数宣言「let / var / const」まとめ

結論としましては、変数宣言キーワードはconstを使いましょう。

constは変数の中身が変わらないのでバグを防ぎやすく、コードの意図が明確にできるメリットがあります。

一方で、変数の中身をあとで変える、またはループ処理などで変数の中身が変わる場合はletを使いましょう。

なお、varは再宣言ができたり、スコープの扱いが特殊だったり、バグの原因になりやすいので使わないようにしましょう。

まとめ
  • 変数宣言はどんな変数を作るかをプログラムに伝えるためのもの
  • 変数宣言キーワードはvar / let / constの3種類ある
  • constを優先的に使う
  • letは必要なときにだけ使う
  • varは基本的には使わない