【初心者向け】変数をvarで宣言してはいけない理由とは?【JavaScript】
JavaScriptで変数・定数を宣言する場合は、以下の3つのどれかの方法で定義します。
// ① varで変数を定義
var index = 0;
//(index = 0 のように、省略して書いてもvarで宣言した場合と同じようになります。)
// ② letで変数を定義
let index = 0;
// ③ constで定数を定義
const index = 0;
しかし、実は①varで変数を宣言する方法は、現在では徐々に使われなくなってきています。
それどころか、利用を非推奨とする声もあるほどです。
今回は、なぜJavaScriptでvarを使わない動きになっているか、その理由について解説します。
(※公式的に非推奨な機能ではないため、何らかの欠陥・インシデントがあるから使ってはダメというものではありません。)
【結論】スコープの範囲がグローバルだから
varの問題点を理解する上で重要なのが、プログラムにおける「スコープ」の概念です。
例えば、以下のようなプログラムがあるとします。
let count = 0;
// 変数countの数値を1ずつ増やしていく
function countAddOne() {
// 3以上になったら true
let isCountComplete = count >= 3;
// 3未満の場合は加算、そうでない場合はcountを1に戻す
if (!isCountComplete) {
count++;
} else {
count = 1;
}
}
setInterval(function () {
countAddOne();
console.log(count);
console.log(isCountComplete)
}, 1000);
簡単に説明すると、実行すると変数countの値が関数countAddOneによって増えていき、ログに出力されるプログラムです。
なお、上記サンプルコードの変数はすべてletで定義しています。
確認用に、関数countAddOneの中で定義されている変数isCountCompleteの結果を書き出そうとしています。
ただ、実際に実行すると、ログには以下のように出力されます。

console.log(count) の部分で出力している数字データは正常に出力されている一方で、変数isCountCompleteの方は「そんな変数定義されてないよ!」とエラーが出ています。
あくまで変数isCountCompleteは関数countAddOneの中で定義されているものであり、変数isCountCompleteは関数countAddOneの中でのみ機能しているのです。
これはすなわち、関数countAddOneのスコープ内でのみ機能している状態と言い換えられます。
したがって、当然ながらスコープ外であるsetInterval内のコールバック処理から呼び出そうとすると、エラーが発生するわけです。
では、今度は変数isCountCompleteを以下のようにvarで定義してみましょう。
// 3以上になったら true
var isCountComplete = count >= 3;
恐らく、以下のように出力されるはずです。

ご覧のように、遠く離れた変数isCountCompleteの値を取得することができてしまいました。(エラーになってない)
この程度の簡単なプログラムなら、一見すると便利そうに思えるかもしれませんが、「index」のように、簡単な名前の変数を全てvarで宣言されていると、処理の途中でなぜか入るはずのない数値が代入されてしまうなんていうトラブルに繋がる恐れもあります。
はっきり言って、共同開発では迷惑極まりない話です。
上記コードの場合は、関数内でvarを使って宣言するのではなく、変数countと同じようなスコープで、letを使って定義してもらった方が、プログラムの可読性も高まります。
とりわけ複数人でJavaScriptファイルを扱うことも多い現代において、varを使って変数を宣言することは破壊行為のようなものなので、基本的にはletとconstを使って宣言していくのが良いでしょう。
varで宣言することはある?
varで変数を宣言するのは基本的にNGではありますが、「絶対的なグローバル変数」であることをコードの閲覧者に伝えるため、わざわざvarで宣言することもあります。
例えば、先ほどのサンプルコードでは変数countをletで宣言していましたが、それだと何も知らない人がコードを見た際に「部分的に使われている変数なのかな?」と予想してしまいます。
サンプルコードにおいて、変数countはsetIntervalの処理でも呼び出されているなど、多くの場所で使いまわされることが予想されますから、そういった「JavaScriptの処理においてどこからでも呼び出されているような、非常に広い影響を持った変数」は、あえてvarで宣言することで、「この変数は本当に色んなところで使われている」という情報を暗に伝えることが可能なのです。
もちろん、コメントアウトやwindowオブジェクトのプロパティでも同じことはできるわけですが、そこはまあ、感覚で使い分けていくのも面白いでしょう。
まとめ
現代ではJavaScriptを学習する際に、皆「varで宣言するな!」と教わると思います。
ただ、実際のところ「varで宣言するのが絶対ダメな理由」があるかと言われると、何とも言えません。
varで宣言することによってトラブルが起こる場合、そもそもプログラム自体の構成が良くなかったり、コードが汚かったりと、プロジェクトの内容・環境が良くない可能性が高いからです。
ただ、わざわざvarを使う必要性自体は無いと言っても過言ではないので、JavaScriptを学習中の方はletとconstを主体に変数を宣言していくべきでしょう。