
スポンサーリンク
本記事ではvar,let,constの違いをサンプルコードを交えて、解説します。
varは関数スコープで再宣言・再代入が可能で、letはブロックスコープで再宣言が不可ですが、再代入は可能です。constはブロックスコープで再宣言・再代入いずれもできません。
var,let,constの違い
それぞれの違いを表でまとめると以下の通りです。
種類 | 概要 | スコープ | 再宣言 | 再代入 | 巻き上げ |
---|---|---|---|---|---|
var | ローカル変数を定義する | 関数 | 〇 | 〇 | 〇 |
let | ローカル変数を定義する | ブロック | × | 〇 | △(TDZ ※後述) |
const | 定数を定義する | ブロック | × | × | △(TDZ ※後述) |
var変数の説明
varで定義した変数は以下のような挙動となります。
- JavaScriptで宣言できるローカル変数
- 宣言された関数内で利用できる(ブロック外から参照可能)
- 再宣言・再代入ともに可能
- 巻き上げ(Hoisting): var で宣言された変数は、スコープの先頭に巻き上げられる。(※巻き上げの詳細については後述。)
var再宣言(実行コード)
以下再宣言の確認コードです。
var hoge = 1;var hoge = 2; // 再宣言できるconsole.log(hoge);
var再宣言(実行結果)
再宣言した値が表示されることを確認できました。
2
var再代入(実行コード)
以下再代入の確認コードです。
var hoge = 1;hoge = 3; // 再代入できるconsole.log(hoge);
var再代入(実行結果)
再代入した値が表示されることを確認できました。
3
varスコープ(実行コード)
以下関数スコープの確認コードです。
if (true) { var num = 100; console.log("ブロック内:" + num);}// ブロック外から参照可能console.log("ブロック外:" + num);
varスコープ確認(実行結果)
ブロック外から値が参照できることが確認できました。
ブロック内:100ブロック外:100
let変数の説明
letで定義した変数は以下のような挙動となります。
- JavaScriptで宣言できるローカル変数
- 宣言されたブロック
{ }
内でのみ利用できる - 再宣言は不可であるが、再代入は可能
- 巻き上げ(Hoisting): 変数はスコープの先頭に巻き上げられますが、実際に宣言されるまでは使用できない。 (一時的デッドゾーン:TDZ(Temporal Dead Zone))
let再宣言(実行コード)
以下再宣言の確認コードです。
let hoge = 1;let hoge = 2; // 再宣言不可console.log(hoge);
let再宣言(実行結果)
再宣言がエラーとなることを確認できました。
let hoge = 2; // 再宣言不可 ^
SyntaxError: Identifier 'hoge' has already been declared
let再代入(実行コード)
以下再代入の確認コードです。
let hoge = 1;hoge = 3; // 再代入できるconsole.log(hoge);
let再代入(実行結果)
再代入できることを確認できました。
3
letスコープ(実行コード)
以下ブロックスコープの確認コードです。
if (true) { let num = '100'; console.log(num);}// ブロック外からは参照不可console.log(num);
letスコープ(実行結果)
ブロック外から値が参照できないことを確認できました。
console.log(num); ^
ReferenceError: num is not defined
const定数の説明
constで定義した変数は以下のような挙動となります。
- JavaScriptで宣言できる定数
- 宣言されたブロック
{ }
内でのみ利用できる - 再宣言・再代入ともに不可
- 巻き上げ(Hoisting): 変数はスコープの先頭に巻き上げられるが、実際に宣言されるまでは使用できない。 (一時的デッドゾーン:TDZ(Temporal Dead Zone))
const再宣言(実行コード)
以下再宣言の確認コードです。
const hoge = 1;const hoge = 2; // 再宣言は不可
const再宣言(実行結果)
再宣言がエラーとなることを確認できました。
const hoge = 2; // 再宣言は不可 ^
SyntaxError: Identifier 'hoge' has already been declared
const再代入(実行コード)
以下再代入の確認コードです。
const hoge = 1;hoge = 3; // 再代入は不可
const再代入(実行結果)
再代入がエラーとなることを確認できました。
hoge = 3; // 再代入は不可 ^
TypeError: Assignment to constant variable.
constスコープ確認(実行コード)
以下ブロックスコープの確認コードです。
if (true) { const num = '100'; console.log(num);}// ブロック外からは参照不可console.log(num);
constスコープ確認(実行結果)
ブロック外から値が参照できないことを確認できました。
console.log(num); ^
ReferenceError: num is not defined
巻き上げ(Hoisting)について
巻き上げ(Hoisting) とは、JavaScriptの変数や関数の宣言が、スコープの先頭に持ち上げられる(ように見える)動作を指します。ただし、宣言のみが巻き上げられ、値の代入はその場で行われるため、未初期化の状態でアクセスすると undefined
になることがあります。
var
の場合
var
で宣言された変数は、スコープの最上部に巻き上げられますが、初期化は実際の宣言位置で行われます。
console.log(x); // undefinedvar x = 5;console.log(x); // 5
var
の巻き上げの具体例
以下のコードを考えてみます。
var username = "global";console.log(username);function showName() { console.log(username); var username = "local"; console.log(username);}
showName();
このコードの実行結果は以下のようになります。
globalundefinedlocal
2行目がundefinedになる理由:
var username
は関数スコープ内で巻き上げられます。そのため、showName
内でvar username;
が関数の先頭に移動したとみなされます。- しかし、変数の初期化(代入)はその場で行われるため、
console.log(username);
の時点ではusername
はundefined
になっています。 username = "local";
が実行された後、console.log(username);
により"local"
が出力されます。
このように var
はスコープの先頭に巻き上げられるため、意図しない undefined
が出力されることがあります。そのため、通常は let
や const
を使用することが推奨されます。
let
・const
の場合
let
や const
で宣言された変数も巻き上げられますが、それらは「一時的デッドゾーン(TDZ: Temporal Dead Zone)」に入り、初期化されるまでアクセスできません。
letの場合
console.log(y); // ReferenceError: Cannot access 'y' before initializationlet y = 10;console.log(y); // 10
constの場合
console.log(y); // ReferenceError: Cannot access 'y' before initializationconst y = 10;console.log(y); // 10
まとめ
- スコープ・再宣言・再代入の自由度は
var > let > const
となる。 var
の再宣言や関数スコープは、意図しないバグを引き起こす場合があるため、基本的にはlet
やconst
の利用が推奨される。
以上で本記事の解説を終わります。
よいITライフを!