JavaScriptにおける変数の宣言方法は、constを除くと以下の4つがあります。
・未宣言
1 |
var1 = "var1"; |
のように、値が代入された時点で変数が宣言されたものとみなされる。
・var
1 |
var var1; |
のように、var句により変数を宣言する。
・var(巻き上げ)
1 2 |
var1 = "var1"; var var1; |
のように値が代入された後にvarにより変数が宣言された場合、変数が宣言された後に値が代入されたものとみなされる。
この例では、以下と同価とみなされる。
1 2 |
var var1; var1 = "var1"; |
・let
1 |
let var1; |
のように、var句により変数を宣言する。
ES6のバージョン以降でサポートされている。
これらの宣言方法の違いにより、非Strictモードの場合に以下の挙動の違いが生じます。
(varの巻き上げについては、巻き上げしなかった場合と同じです)
なお、Strictモードの場合は、varやletやconstを用いて宣言をせずに変数に値を代入した場合にReferenceErrorで異常終了するようになります。
以下、挙動を確認するためのサンプルコードです。
(Node.jsで確認します)
それぞれの変数で以下を確認します。
・var1
ブロック外で宣言した変数をブロック内でも宣言。
ブロック内の変更がブロック外に影響するなら、ブロックを出た時点で変数が書き変わる。
・var2
ブロック内でのみ変数を宣言。
ブロック内の変更がブロック外に影響するなら、ブロックを出た時点で参照不可になる。
・var3
関数内でのみ変数を宣言。 関数内の変更が関数外に影響するなら、関数を出た時点で参照不可になる。
【テストコード(未宣言)】
・test.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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); |
【実行結果(未宣言)】
1 2 3 4 5 6 7 8 9 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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)】
1 2 3 4 5 6 7 8 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
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巻き上げ)】
1 2 3 4 5 6 7 8 |
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
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)】
1 2 3 4 5 6 7 |
c:\tmp>node test.js before change :var1 in block :var2 after change :var1 in function :var3 c:\tmp> |
いかがでしたでしょうか。
この記事では、JavaScriptの変数宣言の違いによる挙動の違いをまとめてみました。
色々と書きましたが、現在の実務ではletを使うのが無難です。
letであれば、Javaの変数と同じような感覚で使うことができます。
コメント