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モードの場合は、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>
いかがでしたでしょうか。
この記事では、JavaScriptの変数宣言の違いによる挙動の違いをまとめてみました。
色々と書きましたが、現在の実務ではletを使うのが無難です。
letであれば、Javaの変数と同じような感覚で使うことができます。


コメント