まずはこちらをご覧ください。
var num = 1;
console.log(num); // -> 1
if(num === 1) {
var num = 1234;
console.log(num); // -> 1234
}
console.log(num); // -> 1234
_人人人人_
> 1234 <
 ̄Y^Y^Y^Y ̄
なぜこうなるのか
原因1: var
にはブロックスコープがない
var 文は関数スコープまたはグローバルスコープの変数を宣言し、任意でそれをある値に初期化します。
MDN
ブロックスコープ(if 文や for 文の波括弧の中のスコープ)がないということはつまり、冒頭のコードでは var num = 1;
と var num = 1234;
が同じスコープで宣言されているということ。これが前提になってきます。
原因2: var
には再宣言がある
var
を使ってすでに宣言されている宣言をもう一度宣言することができます。
その場合 var
は無視され、再代入のような動きになるようです。
var myName = "はたらく電灯"
var myName = "はたらかない電灯"
console.log(myName); // -> "はたらかない電灯"
つまりどういうこと?
冒頭のコードをもう一度見てみましょう。
var num = 1;
console.log(num); // -> 1
if(num === 1) {
var num = 1234;
console.log(num); // -> 1234
}
console.log(num); // -> 1234
-
var
を使用し、num
という変数を宣言 - if 文の中で
var
を使用し、num
という変数を宣言している。let
やconst
であればブロックスコープの中で宣言したという扱いになり変数名は衝突しないが、var
にはブロックスコープがないため、変数名が衝突。再宣言が起きて1行目のnum
の中身が書き換わってしまう -
num
が 1234 になる
感想
var
をコントロールしながらコードを書くのはとっても大変ですね。
私が JavaScript を学び始めたのは 2020 年ごろなので、学習初期ですでに let
, const
のみを使用しており、実は var
の動きをよく知りませんでした。想像以上に気持ち悪くてびっくりしました。おもしろい。二度と使いません。
参考