var や let や const とは?
それぞれのキーワードには、簡単に言うと以下のような違いがあります。
しかし、次のような疑問が湧いてくるのではないでしょうか…
この記事では、そんな疑問や var と let と const の違いについて初心者向けに解説します。
var と let と const の違い
変数や定数を宣言する際に使用する var と let と const ですが、それぞれに違いがあり、何を使っても良いわけではありません。
注意ポイント
そこで、それぞれの違いを詳しく分類したものを以下の表にまとめてみました。
再宣言 | 再代入 | スコープ | 巻き上げ | |
const | × | × | ブロック、関数 | エラー |
let | × | ○ | ブロック、関数 | エラー |
var | ○ | ○ | 関数のみ | undefined |
- 再宣言 / 再代入 … 文字通り、一度宣言または代入した変数に、再び宣言又は代入すること
- スコープ … 変数の有効範囲
- 巻き上げ … 宣言を行う前にも有効範囲が及ぶこと
ご覧の通り、それぞれの宣言方法にも、微妙に出来ることが異なるのがわかると思います。
再宣言と再代入
再宣言とは、文字通り変数を宣言した後、再度宣言することで、再代入は一度値を代入した後、再度代入することです。
const は、再宣言も再代入もできず、 let は再代入が可能で、 var はいずれも可能となっています。
再宣言 | 再代入 | |
const | × | × |
let | × | ○ |
var | ○ | ○ |
では実際に、再宣言すると、どのような結果になるか見てみましょう。
</>javascriptvar は問題なく参照できていますが、var test1 = '1回目';
var test1 = '2回目';
console.log(test1); // 2回目
let test2 = '1回目';
let test2 = '2回目'; // SyntaxError: Identifier 'test2' has already been declared
const test3 = '1回目';
const test3 = '2回目'; // SyntaxError: Identifier 'test3' has already been declared
let と const は再宣言出来ずに、「SyntaxError: Identifier '○○' has already been declared」というエラーが発生してしまいます。
では、再代入した場合はどうでしょうか、
</>javascriptvar も let も再代入出来ていますが、const でエラーが発生していますね。var test1 = '1回目';
test1 = '2回目';
console.log(test1); // 2回目
let test2 = '1回目';
test2 = '2回目';
console.log(test2); // 2回目
const test3 = '1回目';
test3 = '2回目'; // TypeError: Assignment to constant variable.
と思うかもしれませんが、var は自由度が高い分、気付かぬうちに同じ名前で宣言して値を上書きしてしまうというデメリットがあります。
変数宣言とスコープ
スコープとは、変数の有効範囲のことです。
基本的には有効範囲内の変数や定数にアクセスできても、有効範囲外のものにはアクセスすることは出来ません。
const と let は、ブロックスコープと関数スコープを持ち、var は関数スコープのみを持ちます。
スコープ | |
const | ブロック、関数 |
let | ブロック、関数 |
var | 関数のみ |
では実際に、ブロックスコープについて確認してみましょう。
</>javascriptvar で宣言した変数のみブロックスコープの外から参照することができ、それ以外の let と const ではif(true){
var test1 = 1;
let test2 = 2;
const test3 = 3;
}
console.log(test1); // 1
console.log(test2); //ReferenceError: test2 is not defined
console.log(test3); //ReferenceError: test3 is not defined
「ReferenceError:○○ is not defined」というエラーが出てしまいます。
このように、var はスコープが広く、ブロックスコープ内で宣言した変数も外部で上書き可能となっています。
注意ポイント
念のため、関数スコープについても確認します。
</>javascriptvar も let も const も全て、先程と同様のエラーが出て参照できませんでした。function myFunc(){
var test1 = 1;
let test2 = 2;
const test3 = 3;
}
console.log(test1); //ReferenceError: test1 is not defined
console.log(test2); //ReferenceError: test2 is not defined
console.log(test3); //ReferenceError: test3 is not defined
変数の巻き上げ(ホイスティング)
変数の巻き上げとは、変数の有効範囲が宣言を行う前にも及ぶことです。
巻き上げが発生した場合、const と let はエラーとなり、var はエラーにならずに、undefinedになります。(※Undefinedとは、未定義を表す値のことです。)
巻き上げ | |
const | エラー |
let | エラー |
var | undefined |
では、実際に変数の巻き上げについて確認してみましょう。
</>javascript最初のコンソールで「1」が表示され、内側のブロックスコープの内で宣言している変数を参照すると「2」が表示されます。if(true){
let test = 1;
console.log(test); // 1
if(true){
let test = 2;
console.log(test); // 2
}
}
今度は、この内側のブロックスコープ内の「console.log(test);」を同じスコープ内の宣言の直前に移動してみるとどうでしょうか。
</>javascript一つ上の階層で宣言された変数を参照するので「1」が表示されると思いきや、「ReferenceError: Cannot access 'test' before initialization」というエラーが発生してしまいます。if(true){
let test = 1;
console.log(test); // 1
if(true){ console.log(test); // ReferenceError: Cannot access 'test' before initialization
let test = 2;
}
}
これは、すぐ下で宣言している変数に影響を受けているためです。
と言うのも、javascriptはスコープ内で変数が宣言された場合、そのスコープの先頭で宣言された場合と同じように動作するという仕様になっているからです。
注意ポイント
3つの宣言方法のまとめ
これまで説明してきた var と let と const の違いを踏まえ「varは使わないの?」や「letやconstはいつ使うのか?」といった疑問についてまとめてみました。
var は 非推奨? 使わない?
var は、互換のために残ったES5以前からある古い変数宣言です。
- 再宣言や再代入ができるため、同じスコープ内で何度も宣言や代入が可能です。
- 変数の巻き上げによってエラーを吐きません。
これらの特徴により、気付かぬうちに同じ名前で変数を宣言し、値を上書きしてしまったり、巻き上げ時に思わぬバグを誘発してしまう恐れがあります。
明確に非推奨とはされていませんが、出来るだけletやconstを使用するべきでしょう。
let や const の使い分け方は?
let は変数を宣言する時に、const は定数を宣言するときに使用します。
- どちらのスコープもブロックスコープです。
- letは再代入ができますが、const は再宣言も再代入もできません。
- let も const も巻き上げ時にエラーが発生します。
つまり、const を使用していれば、後で誤って値を上書きしてしまう恐れがありません。
最後に
いかがでしたでしょうか、今回は let と var と const の3つの宣言方法の違いについて解説しました。
もっと詳しく学習したい方は、下の記事一覧から他の記事もご覧下さい。
Javascript
javascriptの基本的な使い方について解説した記事一覧ページです。
イラストを交えてやさしく解説していますので、ぜひご覧ください。続きを見る