JavaScriptの変数var, let, constの違いや使い分け方を徹底解説!
JavaScriptでは主にvar、let、constという3つの異なる方法で変数を宣言することができます。
これらの違いとそれぞれの最適な使い方を理解することは、JavaScriptを効率的で効果的に使用にすることができます。
本記事ではこのvar、let、constのそれぞれの違いや使い分け方を解説していきますので、ぜひ最後まで読んでいただけたらと思います。
DMM WEB CAMP
未経験者のために開発されたカリキュラムで、現役エンジニアによる充実したサポート体制。最短3ヶ月でITエンジニアへ転職を目指すことが可能。
入学金 | 0円 |
料金 | 169,800円(税込)〜 |
学び方 | オンライン(自習形式) |
校舎 | ー |
保証制度 | 8日間返金保証 早期卒業返金保証 |
就職サポート | ○ |
運営会社 | 株式会社インフラトップ |
おすすめのプログラミングスクールに関しては【初心者用】フリーランスも目指せる!おすすめのプログラミングスクール16選で詳しく解説していますので、興味ある方はぜひチェックしてみてください。
レバテックフリーランス
業界最大級の案件数を誇るフリーランスITエンジニア向けのサービス。専門アドバイザーによる案件提案と全面的なサポートを提供。
案件数 | 50,000件以上 |
リモート | ○ (半分くらいがリモート対応) |
単価 | 45万 〜 195万円 |
稼働日数 | 週5日が多め |
福利厚生 | ◎ |
運営会社 | レバテック株式会社 |
フリーランスエンジニア向けのおすすめのエージェントに関してはフリーランスエンジニア・プログラマー用エージェントでおすすめはどこ?12社を徹底比較で詳しく紹介してますので、興味ある方はぜひチェックしてみてください。
そもそも変数とは?
変数とは、プログラムがデータを一時的に保存して再利用するための箱のようなものです。
変数を使うことで、異なるタイプの情報(文字列、数値、オブジェクトなど)を保存し、それらをプログラム全体で使用したり、操作したりすることができます。
後に詳しく説明しますが、JavaScriptではvar、let、constの3つのキーワードを使って変数を宣言することができます。
script.js
1var name = 'John Doe';
2let age = 25;
3const city = 'New York';
この例では、nameという変数には’John Doe’という文字列が、ageという変数には25という数値が、cityという変数には’New York’という文字列がそれぞれ格納されています。
※変数の名前(識別子)には、いくつかのルールがあります。
例えば、英字(大文字と小文字)、数字、アンダースコア(_ )、およびドル記号($)を使うことができますが、名前の最初の文字は数字にできません。
var、let、constの違い
var、let、およびconstはJavaScriptの変数宣言に使用される変数で、それぞれ異なる挙動とスコープを持っています。
以下は、これら3つの変数の比較表です。
var、let、constの比較表
var | let | const | |
---|---|---|---|
スコープ | 関数スコープ | 関数と ブロックスコープ | 関数と ブロックスコープ |
再宣言 | ○ | × | × |
再代入 | ○ | ○ | × |
初期化 | 宣言後に 初期化する必要がある | 宣言と同時に 初期化する必要がある | 宣言と同時に 初期化する必要がある |
ホイスティング (巻き上げ) | 宣言がスコープの 先頭に移動する | 初期化の前に アクセスするとエラー | 初期化の前に アクセスするとエラー |
スコープ
スコープとは、変数や関数がアクセス可能な範囲のことです。
JavaScriptには主に「グローバルスコープ」と「ローカルスコープ」があります。
さらに、ローカルスコープは「関数スコープ」と「ブロックスコープ」に分けることができます。
以下具体例です。
グローバルスコープ
1var globalVar = "私はグローバル変数です"; // グローバルスコープでの宣言
2
3function showGlobalVar() {
4 console.log(globalVar); // グローバルスコープの変数にアクセス
5}
6
7showGlobalVar(); // "私はグローバル変数です"と出力される
ローカルスコープ(ブロックスコープ/関数スコープ)
1//ブロックスコープ(let、constで作られる)
2if (true) {
3 let blockScopedVariable = '私はブロックスコープです';
4 console.log(blockScopedVariable); // '私はブロックスコープです'
5}
6console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
7
8//関数スコープ(varで作られる)
9function myFunction() {
10 if (true) {
11 var functionScopedVariable = '私は関数スコープです';
12 }
13 console.log(functionScopedVariable); // '私は関数スコープです'
14}
15
16myFunction();
17console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
変数の再宣言
再宣言は、同一のスコープ内で同じ名前の変数を二度宣言することを指します。
varでは再宣言が許されることがあるが、letやconstではエラーになります。
1var x = 5; // 初回宣言
2var x; // 同じスコープ内での再宣言が可能(varの場合)
変数の再代入
再代入は、既に宣言された変数に新しい値を代入することです。
varとlet宣言の変数は再代入可能ですが、const宣言の変数は再代入できません。
1let y = 10; // 初回代入
2y = 20; // 同じ変数に新しい値を代入(再代入)
変数の初期化
初期化は、変数を宣言する際に初めて値を設定するプロセスです。
変数の初期値を設定することで、未定義の状態を避けることができます。
1var x = 10; // 変数xを宣言と同時に初期値10を設定
2let y = "hello"; // 変数yを宣言と同時に初期値"hello"を設定
3const z = true; // 変数zを宣言と同時に初期値trueを設定
ホイスティング(巻き上げ)
ホイスティングは、変数宣言がそのスコープの最上部に「持ち上げられる」挙動を指します。
このため、変数を宣言する前に参照することができる場合がありますが、その時点では値はundefined(未定義)になります。
1console.log(a); // undefined
2var a = 5;
3console.log(a); // 5
変数varについて
変数varは、JavaScriptの古いバージョンで主に使用される変数宣言の方法です。
JavaScriptの初期から存在していたため、長らく変数宣言の主要な方法でした。
しかし、その挙動が時として予測しにくいことから、ES6(ECMAScript 2015)で導入されたletとconstに取って代わられつつあります。
varの基本形
1var a = 5;
2console.log(a); // 5
varのブラウザ互換性
varは基本的にどのブラウザにも対応しています。
旧式ブラウザでは、let
やconstがサポートされていないことがあるため、そのような環境をターゲットとする場合にはvarの使用が必要な場合があります。
varのスコープ
varで宣言された変数は、関数スコープを持つため、変数が宣言された関数全体でアクセスできます。
また、ブロックの中で宣言された場合でも、そのブロックの外からアクセス可能です。
例1: ブロックスコープの外での参照
1if (true) {
2 var x = 10; // この変数xはif文の外でも参照可能
3}
4
5console.log(x); // 10と出力される
上記のコードでは、ifブロック内で宣言されたxがブロックの外でも参照できるため、10という値が出力されます。
例2: 関数スコープの外での参照
varで宣言された変数は関数スコープを持つため、その変数は関数の外から直接参照することはできません。
1function test() {
2 var functionScopedVariable = "私は関数スコープです";
3}
4
5test();
6console.log(functionScopedVariable); // ReferenceError または undefined(スコープ外から参照できない)
この例では、functionScopedVariable変数は関数test内で宣言されているため、その関数の外からは参照することができません。
このコードの実行を試みると、エラーが発生するか、undefinedが出力されることになります。
例3: グローバルスコープでの変数宣言
varを使って変数をグローバルスコープで宣言すると、その変数はプログラム全体からアクセス可能になります。
以下はその具体例です。
1var globalVar = "私はグローバル変数です"; // グローバルスコープでの宣言
2
3function showGlobalVar() {
4 console.log(globalVar); // グローバルスコープの変数にアクセス
5}
6
7showGlobalVar(); // "私はグローバル変数です"と出力される
varの再宣言
var
は同じスコープ内での変数の再宣言ができます。
以下、具体例です。
1var name = "Alice";
2var name = "Bob";
3
4console.log(name); // 出力: "Bob"
このコードでは、同じスコープ内でnameという変数を2回宣言しています。
最初に”Alice”という値を代入し、次に”Bob”という値を再宣言して代入しています。結果として、name変数の値は”Bob”となります。
varの再代入
varを使用して宣言された変数は、同じスコープ内でその値を再代入することができます。
以下は、再代入の具体的な例です。
1var age = 25;
2age = 30;
3
4console.log(age); // 出力: 30
ageという変数に最初に25という値を代入しています。その後、同じ変数ageに30という新しい値を再代入しています。
結果として、変数の値が更新され、30となります。
varの初期化
変数の初期化とは、変数を宣言する際に最初にその変数に値を設定することを指します。
varは初期化することができます。
以下は具体的な例です。
1var name = "Alice";
2console.log(name); // 出力: "Alice"
この例では、nameという変数を宣言し、同時に文字列”Alice”で初期化しています。
初期化された変数はその後のコードで使用することができます。
varを使用して変数を宣言する際に初期値を設定しないと、その変数はundefinedという値が返されます。
1var age;
2console.log(age); // 出力: undefined
この例では、age変数を宣言していますが、初期値を設定していないため、変数の値はundefinedとなります。
varのホイスティング
ホイスティングとは、JavaScriptの変数宣言がコードの実行前にそのスコープの最上部へ移動することを指します。
以下はvarのホイスティングについての具体例です。
1console.log(name); // 出力: undefined
2var name = "Alice";
3console.log(name); // 出力: "Alice"
このコードの実行時、name変数の宣言部分がスコープの最上部へ移動(ホイスティング)されます。
このため、変数nameを宣言する前に出力しようとしても本来ならエラーになるはずがvarの場合はなりません。
ただし、その時点ではname変数はまだ初期化されていないので、値はundefined(未定義)となります。
ホイスティングによって、上記コードの実際の実行順序は以下のように解釈されるのです。
1var name; // 宣言がここに移動
2console.log(name); // 出力: undefined
3name = "Alice"; // 初期化
4console.log(name); // 出力: "Alice"
このように、varで宣言された変数は、そのスコープ内でどこで宣言されているかに関係なく、最上部で宣言されるとみなされます。
この挙動は、初めてJavaScriptを学ぶ際に混乱を招くことがあるため、注意が必要です。
変数letについて
ES6(ECMAScript 2015)の導入により、varの持ついくつかの問題点を解決するためにletという新しい変数宣言の方法が導入されました。
現代のJavaScript開発においては、letが一般的に使用される変数宣言の方法となっています。
特に、変数の値が変更されることが予想される場合に用いられます。
letの基本形
1let a = 5;
2console.log(a); // 5
letのブラウザ互換性
最新のブラウザではletがサポートされていますが、一部の旧式ブラウザではサポートされていないため、対象とするブラウザに応じて注意が必要です。
letのスコープ
letを用いた変数宣言のスコープはブロックと関数スコープです。
つまり、変数はその宣言がされたブロックか関数({}
で囲まれた部分)の中でのみ有効です。
以下はlet
のスコープについての具体例です。
例1: ブロックスコープの外での参照
1if (true) {
2 let x = 10;
3 console.log(x); // 出力: 10
4}
5
6console.log(x); // エラー: x is not defined
この例では、変数xはif文のブロック内で宣言されているため、そのブロックの外からは参照できません。
したがって、ifブロックの外でx
をログに出力しようとすると、エラーが発生します。
例2: 関数スコープの外での参照
1function test() {
2 let functionScopedVariable = "私は関数スコープです";
3}
4
5test();
6console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined
この例では、functionScopedVariable変数は関数test内で宣言されているため、その関数の外からは参照することができません。
このコードの実行を試みると、参照エラーが発生します。
例3: グローバルスコープでの変数宣言
letを使用して変数をグローバルスコープで宣言することも可能です。
以下はその具体例です。
1let globalLet = "私はグローバル変数です"; // グローバルスコープでの宣言
2
3function showGlobalLet() {
4console.log(globalLet); // グローバルスコープの変数にアクセス
5}
6
7showGlobalLet(); // "私はグローバル変数です"と出力される
letの再宣言
letで宣言された変数は、同じスコープ内で再宣言することができません。
以下はletでの再宣言についての具体例です。
1let x = 10;
2let x = 20; // エラー: Identifier 'x' has already been declared
このコードでは、変数x
が同じスコープ内で2回宣言されているため、エラーが発生します。
しかし、異なるスコープ内であれば、同じ名前の変数をletで宣言することができます。
1let x = 10;
2
3if (true) {
4 let x = 20; // 異なるスコープなのでエラーにならない
5 console.log(x); // 出力: 20
6}
7
8console.log(x); // 出力: 10
この例では、if文のブロック内で新しいスコープが作成されるため、ブロック内で再度xを宣言してもエラーにはなりません。
しかし、ブロックの外でのxとブロック内でのx
は異なる変数となるため、それぞれの値が正しく出力されます。
このように、letは同じスコープ内での再宣言を許可しないため、変数の名前の衝突や予期せぬバグを防ぐのに役立ちます。
letの再代入
letで宣言された変数は、値の再代入が可能です。
以下は具体例です。
1let age = 25; // 初期値を25に設定
2console.log(age); // 出力: 25
3
4age = 30; // 25から30に再代入
5console.log(age); // 出力: 30
この例では、age変数に初期値25が割り当てられ、次にその値が30に再代入されています。
letを使用することで、変数に値を再代入する必要がある場合でも、同じスコープ内での再宣言を防ぐことができるため、コードがより安全で可読性が高くなります。
letの初期化
letを使用して変数を宣言する際、初期化することが可能です。
初期化とは、変数に最初の値を割り当てることを指します。以下は具体例です。
1let name; // 変数の宣言だけで、値は未割り当て (undefined)
2console.log(name); // 出力: undefined
3
4name = 'Alice'; // 初期化、初めて値を割り当てる
5console.log(name); // 出力: Alice
この例では、name変数が最初に宣言される際、値は割り当てられずundefinedとなります。
その後、値’Alice’が変数に割り当てられ、初期化されます。
変数の初期化はプログラミングにおいて一般的な操作で、特定の値で開始する必要がある変数に対して行われます。
letを使用することで、変数の値が必要に応じて変更される場合でも、変数の再宣言を防ぐことができます。
letのホイスティング
letはホイスティングの挙動を持ちますが、varとは異なり、宣言された変数はそのスコープのトップに移動されますが、未初期化のままとなります。
その結果、変数が宣言される前に参照するとReferenceErrorが発生します。
具体例を見てみましょう。
1console.log(name); // ReferenceError: name is not defined
2let name = 'Alice';
letで宣言された変数nameはホイスティングされますが、未初期化のままとなるため、変数宣言の前に変数を参照しようとするとエラーが発生します。
varと違い、letでは変数が宣言されるまでその存在がスコープ内で認識されないため、初心者が混乱することが少ないとされています。
変数constについて
constもまた、ES6により導入された新しい変数宣言の方法です。
constは「定数」を意味し、一度定義された値を変更することはできません。つまり、constを使用して宣言された変数は再代入できません。
constの基本形
1const a = 5;
2console.log(a); // 5
constのブラウザ互換性
constは最新のJavaScriptエンジンやブラウザではサポートされています。
しかし、古いブラウザやエンジンにおいてはサポートされていない場合があります。
constのスコープ
const変数のスコープはブロックと関数レベルに制限されます。
以下具体例です。
例1: ブロックスコープの外での参照
1if (true) {
2 const blockScopedVariable = "私はブロックスコープです";
3 console.log(blockScopedVariable); // "私はブロックスコープです"と出力
4}
5
6console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined
この例では、blockScopedVariable変数はifブロック内で宣言されているため、ブロックの外部からはアクセスできません。
例2: 関数スコープの外での参照
1function test() {
2 const functionScopedConstant = "私は関数スコープです";
3}
4
5test();
6console.log(functionScopedConstant); // ReferenceError: functionScopedConstant is not defined
この例では、functionScopedConstant定数は関数test内で宣言されているため、その関数の外からは参照することができません。
このコードの実行を試みると、参照エラーが発生します。
例3: グローバルスコープでの参照
constで宣言された変数はブロックスコープを持ちますが、もしその変数がコードの最上位レベルで宣言された場合、グローバルスコープに存在することになります。
この場合、その変数はコード内のどこからでも参照することができます。
1const globalVariable = "I'm globally scoped";
2
3function test() {
4 console.log(globalVariable); // "I'm globally scoped"と出力
5}
6
7test();
8console.log(globalVariable); // "I'm globally scoped"と出力
この例では、globalVariable変数はコードの最上位レベルで宣言されているため、グローバルスコープに存在します。
そのため、関数test内やその他の場所からでも参照することができます。
constを使用すると、変数の再代入が不可能になるとともに、ブロックスコープを強制するため、コードの読みやすさと保守性が向上します。
constの再宣言
constでは、同じ名前の変数を再宣言することはできません。
一度constで宣言された変数名は、同じスコープ内で再び使用することができないのです。
以下のコードを見てみましょう。
1const name = 'John';
2const name = 'Doe'; // SyntaxError: Identifier 'name' has already been declared
この例では、変数nameが既にconstで宣言されているため、同じ名前で再宣言しようとするとエラーが発生します。
異なるスコープであれば同じ名前の変数を宣言できるため、以下のようなコードは問題ありません。
1const name = 'John';
2
3if (true) {
4 const name = 'Doe'; // 別のスコープなのでエラーにならない
5}
constの再代入
constを使用して変数を宣言すると、その変数に対する再代入が不可能になります。
以下具体例です。
1const age = 30;
2age = 40; // TypeError: Assignment to constant variable.
このコードでは、ageという変数に対してconstを使用して宣言しているので、値の再代入はできません。
再代入を試みると、エラーが発生します。
ただし、constで宣言されたオブジェクトや配列のプロパティは変更可能です。
以下のような例ではエラーになりません。
1const person = { name: 'John' };
2person.name = 'Doe'; // これはOK
この例では、person変数自体への再代入が禁止されているだけで、オブジェクトのプロパティに対する変更は許可されています。
constの初期化
constを使用して変数を宣言する際は、その時点で初期化(値の割り当て)が必要です。
constで宣言された変数は、一度だけ値を割り当てることができ、その後の再代入はできません。
具体的な例を見てみましょう。
1const name; // SyntaxError: Missing initializer in const declaration
このコードでは、constで変数nameを宣言していますが、初期化せずに宣言しているため、エラーが発生します。
正しい使い方は以下のように、宣言と同時に初期値を割り当てる必要があります。
1const name = 'John'; // これはOK
constのホイスティング
const
に関してもホイスティングが適用されますが、重要な点として、const(およびlet
)でのホイスティングはvarとは異なる挙動をします。
1console.log(name); // ReferenceError: Cannot access 'name' before initialization
2const name = 'John';
このコードでは、name変数の宣言より前にその変数を参照しています。
varの場合、変数は宣言されているもののundefinedとして初期化されるため、エラーにはなりませんが、constの場合はエラー(参照エラー)となります。
これは、constとletの変数が、そのスコープの最上部で物理的にホイスティングされるわけではなく、一時的なデッドゾーン(Temporal Dead Zone、TDZ)という状態が存在し、変数の宣言・初期化より前にアクセスすることはできないからです。
var, let, constの使い分け
var, let, constの違いを理解した上で、どのキーワードを使うべきかはコードの要件と、あなたのスタイルガイド、チームプロジェクトならそのチームの慣習によって変わってきます。
しかし、一般的なガイドラインとしては次のようになります。
可能な限りconstを使用する
constを使用すると、変数の再代入が不可能になるため、コードの安定性と保守性が向上します。
変数が持つべき値に対して一貫性を保ち、読み手にとって予測しやすくする効果もあります。
ただし、オブジェクトや配列の内容は変更できるため、constが変数自体の再代入のみを阻止することに注意が必要です。
一度だけ代入が必要な設定や定数などに適しています。
再代入が必要な場合はletを使用する
letは再代入が必要な場合に使用します。
ブロックスコープを持ち、varよりも厳密な挙動を提供するため、ループ内のカウンター変数や状態が変化する変数に適しています。
varは古いコードベースや特定のケースでのみ使用する
varは主にES6以前のコードのメンテナンスや特殊なケースで使用。
ただし、現代のJavaScript開発では推奨されていない場合が多いです。
まとめ
以上、JavaScriptの変数var、let、constの違いや使い分け方についての徹底解説でした。
ぜひ、うまく使い分けて、効率よくコードが書けるように練習してみましょう。