JavaScriptにおける変数の宣言方法は、constを除くと以下の4つがあります。
・未宣言
var1 = "var1";
のように、値が代入された時点で変数が宣言されたものとみなされる。
・var
var var1;
のように、var句により変数を宣言する。
・var(巻き上げ)
var1 = "var1";
var var1;
のように値が代入された後にvarにより変数が宣言された場合、
変数が宣言された後に値が代入されたものとみなされる。
この例では、以下と同価とみなされる。
var var1;
var1 = "var1";
・let
let var1;
のように、var句により変数を宣言する。
ES6のバージョン以降でサポートされている。
これらの宣言方法の違いにより、非Strictモードの場合に以下の挙動の違いが生じます。
(varの巻き上げについては、巻き上げしなかった場合と同じです)
なお、Strictモード(https://cyzennt.co.jp/blog/2021/04/01/javascript%EF%BC%9Astrict%E3%83%A2%E3%83%BC%E3%83%89%E3%81%A8%E3%81%AF/)の場合は、varやletやconstを用いて宣言をせずに変数に値を代入した場合にReferenceErrorで異常終了するようになります。
----
以下、挙動を確認するためのサンプルコードです。
(Node.jsで確認します)
それぞれの変数で以下を確認します。
・var1
ブロック外で宣言した変数をブロック内でも宣言。
ブロック内の変更がブロック外に影響するなら、
ブロックを出た時点で変数が書き変わる。
・var2
ブロック内でのみ変数を宣言。
ブロック内の変更がブロック外に影響するなら、
ブロックを出た時点で参照不可になる。
・var3
関数内でのみ変数を宣言。
関数内の変更が関数外に影響するなら、
関数を出た時点で参照不可になる。
【テストコード(未宣言)】
・test.js
var1 = "var1";
console.log("before change :" + var1);
if (true) {
var1 = "var1mod"
var2 = "var2";
console.log("in block :" + var2);
}
console.log("after change :" + var1);
console.log("out of block :" + var2);
function func() {
var3 = "var3";
console.log("in function :" + var3);
return var3;
}
func();
console.log("out of function:" + var3);
【実行結果(未宣言)】
c:\tmp>node test.js
before change :var1
in block :var2
after change :var1mod
out of block :var2
in function :var3
out of function:var3
c:\tmp>
【テストコード(var)】
・test.js
var var1 = "var1";
console.log("before change :" + var1);
if (true) {
var var1 = "var1mod"
var var2 = "var2";
console.log("in block :" + var2);
}
console.log("after change :" + var1);
console.log("out of block :" + var2);
function func() {
var var3 = "var3";
console.log("in function :" + var3);
return var3;
}
func();
// console.log("out of function:" + var3); // ReferenceError
【実行結果(var)】
c:\tmp>node test.js
before change :var1
in block :var2
after change :var1mod
out of block :var2
in function :var3
c:\tmp>
【テストコード(var巻き上げ)】
・test.js
var1 = "var1";
var var1;
console.log("before change :" + var1);
if (true) {
var1 = "var1mod"
var var1;
var2 = "var2";
var var2;
console.log("in block :" + var2);
}
console.log("after change :" + var1);
console.log("out of block :" + var2);
function func() {
var3 = "var3";
var var3;
console.log("in function :" + var3);
return var3;
}
func();
// console.log("out of function:" + var3); // ReferenceError
【実行結果(var巻き上げ)】
c:\tmp>node test.js
before change :var1
in block :var2
after change :var1mod
out of block :var2
in function :var3
c:\tmp>
【テストコード(let)】
・test.js
let var1 = "var1";
console.log("before change :" + var1);
if (true) {
let var1 = "var1mod"
let var2 = "var2";
console.log("in block :" + var2);
}
console.log("after change :" + var1);
// console.log("out of block :" + var2); // ReferenceError
function func() {
let var3 = "var3";
console.log("in function :" + var3);
return var3;
}
func();
// console.log("out of function:" + var3); // ReferenceError
【実行結果(let)】
c:\tmp>node test.js
before change :var1
in block :var2
after change :var1
in function :var3
c:\tmp>