本記事では、JavaScriptの変数である
「var」「let」「const」について、
それぞれの違いや適切な使い方を説明していく。
var、let、constとは
var、let、constとは、
JavaScriptで変数を宣言する際に使うキーワードのことだ。
例として、以下のように記述することで変数を宣言できる。
# var、let、const それぞれを使って変数を宣言 var testVar = '変数varに代入するよ'; let testLet = '変数letに代入するよ'; const testConst = '変数constに代入するよ';
var、 let、constの違い
では次に本題、
var、let、const それぞれの違いについて説明していく。
再代入、再宣言の違い
var、let、constには、
再代入、再宣言時の挙動に違いがある。
- 再代入は、一度宣言した変数に対し、値を再び代入すること。
- 再宣言は、一度宣言した変数の名前をキーワードごと丸ごと宣言しなおして、上書きすること。
では再代入と再宣言、
それぞれのケースでより詳しく違いを説明していく。
① 再代入
再代入におけるvar、let、constの違いは結論から言うと、
constのみ、再代入が不可能と言う点である。
varは再代入が可能。
var testVar = '1回目の代入'; testVar = '2回目の代入'; #OK
letでも再代入が可能。
let testLet = '1回目の代入'; testLet = '2回目の代入'; #OK
constだけは再代入をしようとするとエラーになる。
const testConst = '1回目の代入'; testConst = '2回目の代入'; #エラーとなり代入できない
「一度値を入れたら再代入できない変数」のことを、プログラミングにおいては「定数」と呼ぶ。constと言うキーワードはJavaScriptに限らず、他の言語でも定数を定義するためのキーワードとして使用されているので、知らなかった人はこれを機に「const = 定数 = 再代入できない」と覚えてしまおう。
定数のメリットとしては、一度宣言すると、後に変数の値が書き換わることが不可能なため、ソースの可読性向上や、思わぬ値の再代入によるバグを未然に防ぐと言った保守性的観点のメリットがある。
② 再宣言
再宣言におけるvar、let、constの違いは結論から言うと、
再宣言が可能なのはvarのみと言う点である。
再宣言とは、同じ変数名で再度変数の宣言を行うことだ。以下の例では、「testVar」と言う変数を再宣言しているが、varで宣言しているため問題なくソースコードが動く。
//1回目のvarによる宣言 var testVar = 'var1回目'; //2回目のvarによる宣言 var testVar = '宣言2回目' #varで宣言してるので、再宣言が可能
「再宣言が可能」と書くとメリットのように聞こえるが、これは一転してデメリットでもあると言うことをまず覚えておこう。デメリットである理由は、意図しない再宣言(同じ名前の変数を2回作ってしまった、など)によるバグが発生する可能性があるからだ。
let、constで同じことをしようとするとエラーが出るため、再宣言を予防することができる。
コーディングで厳守したい原則として、「できる限り縛り度の高いルールを採用することで、バグの発生を未然に防ぐ」と言う原則がある。例えば型あり言語でプロパティはまずprivateを検討するといった具合だ。この原則に則れば、まずはletやconstの使用が可能がどうかを優先的に考慮するのが最適と言えるだろう。
スコープの違い
スコープとは、簡単にいうと
「変数の有効範囲」のことだ。
宣言した変数はコード内のどこでも使えるわけではなく、このスコープによって使える範囲が定められている。
varは関数スコープ
varは関数スコープと呼ばれる、
let、constに比べて広いスコープを持っている。
関数スコープと言う名前の通り、ある関数内でvarを用いて宣言した変数は、
その関数内のどこからでも呼び出すことが可能となっている。
function test() { if (true) { //if文の中でvarを宣言 var x = "testだよ"; } console.log(x) // if文の外でコンソール出力しても、test()関数内で宣言したので「testだよ」が出力される }
let, constはブロックスコープ
対して、
let、constはブロックスコープを持つ。
ブロックとは、
{}で括られた処理のことだ。
let、constを使うと、varと違い、
同じ関数内であってもブロックの外側からは変数を呼び出すことはできない。
function test() { if (true) { //if文(ブロック)の中でlet、constで変数宣言 let x = 1; const y = 2; } console.log(x) //if()ブロックの外側なのでエラー(undefined(未定義))となる console.log(y) //constを使った場合も同様 };
これもなるべく「意図しないバグを防ぐ」と言う観点から考えれば、なるべくスコープの狭いlet、constの使用を優先的に検討すると言うのが最適と言えるだろう。
var、let、constの使い分け
var、let、constの大きな違いは、
- 再代入・再宣言が可能かどうか
- スコープが異なる
と言うことは、ここまでの説明で理解できただろう。
では最後に、それぞれの違いが理解できたところで、
var、let、constの使い分けについて解説をしていく。
constの使用を最初に検討すべき
結論から述べると、まず
どんな時でもconstが使用可能かどうかを一番最初に検討するのがベストだ。
ここまで何度も述べてきたように、
再宣言、再代入のどちらもできないことに加えて、スコープも狭いconstは最も制限が多いからこそ、意図しない実装を防ぐ = 安全なキーワードと言うことができる。
プログラマーであるならば、常にリスクを最小限にするコーディングをすることが求められるので、そのリスクが少ないconstを最初に候補として思考するのがベストプラクティスと呼べる。
constを使えないときは、letを使う
とはいえ、constは、再代入、再宣言の制約がキツすぎるので、それだけでは全てのコーディングを行うことは絶対に無理である。そのようにconstだけでは制限がキツすぎるという場合には、次に制約が少ないletの使用を検討しよう。それでも無理、あるいはソースの可読性に問題があるとか、特殊な理由がある時は最も制約が少ないvarの使用を検討しよう。
「const > let > var」の順番で使用を検討する。
ポイントは、まずは制限が多い(=バグが起きにくく安全)ものを優先的に使用する。
let、constは、ECMAScript2015から採用された宣言方法
これは覚えなくても良いことだが、3つの変数の内、
letとconstは、ECMAScript2015※から採用された変数宣言用のキーワードだ。
なので、varに比べて新しく出現したものだ。
裏を返せば元々割とつい最近までvarしか変数定義がなかったと言うこと。
関連記事
参考:https://techacademy.jp/magazine/14872
参考:https://qiita.com/cheez921/items/7b57835cb76e70dd0fc4
「① 再代入」の例は本来 var/let/constについて書かれていると思うのだが全て varになっている
ご指摘ありがとうございます。
おっしゃる通りでした。修正しました。