
今回はJavaScriptの変数宣言である、var/let/constについてまとめました。
変数宣言はプログラミングの中でも基礎の部分なので、
しっかり理解して正しく行えるようになりましょう。
Javascriptの変数宣言の違い
— キョウスケ@WEBエンジニア (@kyosuke_prog) February 18, 2020
var ・・・再宣言:可能、再代入:可能。関数スコープ
let ・・・再宣言:不可、再代入:可能。ブロックスコープ
const・・・再宣言:不可、再代入:不可。ブロックスコープ
初心者の方は難しい理屈は一旦置いておいて、変数はlet、定数はconstを使うようにすればOK。
この記事の目次
var文
古いバージョンの宣言文で、今までは変数も定数もvarで宣言していました。
定数とは、値が変わらないもの
再宣言が可能
すでに使った変数(定数)と同じ名前の変数(定数)を宣言することが可能です。
var str = "aiueo";
console.log(str) //=aiueo
var str = "ABC";
console.log(str) //=ABC
上のように書いてもエラーが出ることなく動きます。
それゆえ間違ったコードに気付きにくく、予期せぬバグにつながる可能性が高まります。
再代入が可能
再代入(別の値を代入すること)が可能なので、変数を扱うことが出来ます。
var str = "aiueo";
console.log(str) //=aiueo
str = "ABC";
console.log(str) //=ABC
関数スコープである
スコープとは、その変数(定数)が使用できる範囲のことだと思ってください。
つまり、関数スコープであるvarで宣言した変数(定数)は、
同じ関数の中ならどこでも使用することができます。
window.onload=function(){
var x = 1;
x++;
if(x > 1){
var y = 1;
}
y++; //yを同じ関数内で宣言しているので使える。
if(x == 1){
var z = 1;
}
z++; //ただし、上記のif文を通らないのでzは使えない。
console.log(x+","+y+","+z) //=2,2,NaN
}
古いブラウザでも動く
varはES5というJavaScriptの古いバージョンから使われていた宣言文です。
そのためIE9などの古いブラウザでも動くというメリットがあります。
let文
ES6(ECMAScript2015)という新しいバージョンから追加された変数の宣言文です。
主に変数を宣言するときに使います。
再宣言が不可能
すでに宣言済みの変数と同じ名前で変数を宣言しようとするとエラーが出ます。
let str = "aiueo";
console.log(str) //=aiueo
let str = "ABC"; //Identifier 'str' has already been declared
console.log(str)
上記のコードは4行目でエラーが出ています。
エラーが出るのは決して悪いことではありません。
不適切な箇所を教えてくれるので、
エラーの内容を見て修正するだけで正しいコードを書くことが出来ます。
良くないコードを書いてもその間違いに気づくことが出来ず、
原因の特定が難しいバグや不具合を引き起こす可能性が高まります。
再代入が可能
letはvarと同じで再代入が可能なので、変数を扱うことが出来ます。
let str = "aiueo";
console.log(str) //=aiueo
str = "ABC";
console.log(str) //=ABC
ブロックスコープである
波カッコで括られた部分のことを言います。
letで宣言した変数(定数)は、宣言したブロックの内側でしか使えません。
window.onload=function(){
let x = 1;
x++;
if(x > 1){
let y = 1;
}
y++; //y is not defined
console.log(x+","+y) //=2,2
}
上記のコードは8行目でエラーが出ています。
yを宣言したのは6行目で、5行目のif文のブロック内で宣言されています。
そして、8行目は5行目のif文のブロック外なので、エラーが出るのです。
このように、letはvarよりも厳密なコードを書くことができます。
古いブラウザでは動かない
ES6から追加された宣言文なので、
ES6に対応していない古いブラウザでは動きません。
しかし、2020年現在でほとんどのブラウザがES6に対応しており、
IE9などのよほど古いブラウザでない限り問題なく使うことが出来ます。
const文
letと一緒にES6から追加された定数の宣言文です。
再宣言が不可能
constもletと同じで再宣言が不可能になっています。
const str = "aiueo";
console.log(str) //=aiueo
const str = "ABC"; //Identifier 'str' has already been declared
console.log(str)
上記のコードは4行目でエラーが出ています。
再代入が不可能
constで宣言された値は初期値から変更することができません。
値を変更しようとするとエラーになるので、
変更予定のない値を扱うにはconstを使うと便利です。
ただし、配列やオブジェクトをconstで宣言した場合、
そのものを変更することは出来ませんが、
中の要素は変更することが出来るという点には注意しておきましょう。
const pai = 3.14;
pai = 3.141592; //Assignment to constant variable.
console.log(pai);
上記のコードは2行目でエラーが出ています。
const array = ["A","B","C"];
array[0] = "D";
console.log(array); //=["D", "B", "C"]
array = ["X","Y","Z"]; //Assignment to constant variable.
console.log(array);
上記のコードは4行目まで問題なく動き、6行目でエラーが出ています。
あくまで再代入が不可能なのであり、中身を変えることは出来るのです。
この辺りのconstの仕様についてはしっかり理解しておきましょう。
ブロックスコープである
constもletと同じで、宣言した変数(定数)は宣言したブロックの内側でしか使えません。
window.onload=function(){
let x = 2;
if(x < 3){
const pai = 3.14;
x *= pai;
console.log(x); //=6.18
}
x *= pai; //pai is not defined
console.log(x);
}
上記のコードは8行目でエラーが出ています。
古いブラウザでは動かない
letと同じです。letが使える環境ならconstも使えます。
既に述べたように、2020年時点ですでに問題視する必要がなくなりました。
使い分け方
既に述べたように、すでにほとんどのブラウザでES6への対応が進んでいるので、
さほど気にせずにletやconstも使って大丈夫と言えるでしょう。
また、どうしても古いブラウザにも対応したいという場合には、
Babelというコンパイラを使えば古いブラウザで動くコードに変換出来ます。
そして、letとconstは不適切な使い方をするとエラーを出してくれるので、
varよりも厳密なコードを書くことが出来ます。
varで不具合が出る例題
for (var i = 0; i < 3; i++) {
setTimeout(function(){
console.log(i);
}, 1000);
}
上記は「1秒後に i の値を出力する」という処理を3回繰り返すコードです。
処理をミリ秒後に実行するというコードです。
期待している出力結果は「0,1,2」ですが、実際には「2,2,2」になってしまいます。
なぜなら、setTimeoutで1秒待機している間にもfor文は動き続け、
setTimeout内のコードが実行される頃には、とっくに i は2に達しているからです。
これは、varが関数スコープだから起こる不具合です。
ブロックスコープである let を使って i を宣言すれば、
forのループが進んでもforのブロック内の i は変わらないため、
setTimeout内のコードにも i の値が保持されます。
少し複雑ですが、スコープの違いでこのような不具合が発生することがあるのです。
var/let/constの使い分け
上記の理由から、
変数を宣言する時はlet
定数を宣言する時はconst
を使うのが良いでしょう。
定数も全てletで宣言することも可能ではありますが、
積極的にconstを使っておけば、
コードを見返したときに「この値は定数だ」と一目で分かるのでオススメです。
var/let/constの違いまとめ
var ・・・ 再宣言可能、再代入可能、関数スコープ、もう使うべきでない。
let ・・・ 再宣言不可、再代入可能、ブロックスコープ、変数宣言に使う。
const・・・ 再宣言不可、再代入不可、ブロックスコープ、定数宣言に使う。
初心者の方へ
変数を宣言するときは、let
定数を宣言するときは、const
を使うということを意識してコードを書くように癖づけていきましょう。