varでの変数宣言
「var 変数名;」で宣言。値の代入は何度でもできる。更に一度宣言した変数名を複数宣言してもエラーにならない。
スコープは同一の階層もしくはその下層。関数の外側のグローバルな領域でで宣言すると、個々の関数内でもスコープの対象となる。ただし、関数内で宣言したものはその内側のみ。
var変数のスコープ
// グローバル変数を定義
var value1 = "global";
function func1(){
document.write('2.' + value1 + '<br />'); // 2.global
// グローバル変数に値を代入
value1 = "local";
document.write('3.' + value1 + '<br />'); // 3.local
}
document.write('1.' + value1 + '<br />'); // 1.global
func1();
document.write('4.' + value1 + '<br />'); // 4.local
実行結果
1.global
2.global
3.local
4.local
scriptセクションが2つ以上あった場合
1つのhtmlページ内に2つのscriptセクションがあった場合、グローバルなvar変数は別のセクションでも参照可能か実験してみた。
<script>
// 1つめのセクションで変数を定義
var value2 = "hoge";
</script>
<p>...</p>
<script>
// 別のセクションで変数を呼び出し
document.write(value2 + '<br />'); // hoge
</script>
結果はのセクションが別れても値を参照しちゃうみたい。別セクションだからと言って変数のスコープ外だと思っていると痛い目にあうかもしれない^^;
外部ファイルのvar変数
JavaScriptを定義した外部ファイルでvar変数を定義。呼び出し元から変数を参照する
<!-- 「value3」という変数を外部ファイルに定義 -->
<script src="./js/0012_gaibufile_03.js"></script>
<script>
// 外部ファイルの「value3」という変数を参照
document.write(value3 + '<br />'); // gaibu
</script>
外部ファイルの場合も難なく変数の参照が出来てしまうので注意ですね^^;
複数の外部ファイルを読み込みする事もあると思うので、グローバルなvar変数は定義しない方が良いかと
varのおまけ
グローバルなvar変数を定義した後、下層の関数内で同じ変数を定義するとどうなるかを実験
// グローバルなvar変数を定義
var value1 = "global";
function func1(){
document.write('2.' + value1 + '<br />'); // 2.undefined
// 下層関数内でグローバルなvar変数と同名の変数を定義
var value1 = "local";
document.write('3.' + value1 + '<br />'); // 3.local
}
document.write('1.' + value1 + '<br />'); // 1.global
func1();
document.write('4.' + value1 + '<br />'); // 4.global
実行結果
1.global
2.undefinedl
3.local
4.global
同名の変数を下層の関数内の途中で定義すると、関数内の定義箇所以前では「undefined」が返される。同一変数名を使いまわししたバグみたいなものだけど、こんな挙動をするんですねぇ…
letでの変数宣言
「let 変数名;」で宣言。ES6から利用可能。var同様に値の代入は何度でもできるが、一度宣言した変数名をスコープ内で重複して宣言するとエラーになる。
varと同様に一番上の階層で宣言すると個々の関数の中でもスコープの対象となる。
// グローバル領域でlet変数を定義
let value4 = "global";
function func2(){
document.write('2.' + value4 + '<br />'); // 2.global
// グローバル変数に値を代入
value4 = "local";
document.write('3.' + value4 + '<br />'); // 3.local
}
document.write('1.' + value4 + '<br />'); // 1.global
func2();
document.write('4.' + value4 + '<br />'); // 4.local
実行結果
1.global
2.global
3.local
4.local
ただし、letの場合は同一関数内でも、該当セクションの内側でのみ参照可能。ここはJavaっぽい。
function func3(){
if(true){
let value5 = 'セクション内で定義したlet';
var value6 = 'セクション内で定義したvar'
document.write(value5 + '<br />'); // セクション内で定義したlet
document.write(value6 + '<br />'); // セクション内で定義したvar
}
//document.write(value5 + '<br />'); // この行を実行するとエラー
document.write(value6 + '<br />'); // セクション内で定義したvar
}
func3();