JavaScriptのグローバル変数について理解しましょう。
JavaScriptでは関数内にない変数はグローバル変数となります。実際にはWebページを表すオブジェクトのプロパティになります。Webページを表すオブジェクトは何かというとwindowですから、aという変数を宣言すると、window.a でアクセスできるようになります。
動作を確認するプログラムは次のようになります。
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>setInterval sample 1</title> </head> <body> <div id="log" style="position:absolute;"></div><br /> <script> // a0; と書くと a0 not defined エラー // 初期化すると使える // 実体は windowオブジェクトへa0というプロパティが // 追加される a0 = 'a0'; // 下記のようにするとwindowオブジェクトへa1という // プロパティが追加できる window.a1 = 'a1'; // var をつけると変数宣言できる // 実体は windowオブジェクトへb0というプロパティが // 追加される var b0; // 初期化もできる // 実体は windowオブジェクトへb1というプロパティが // 追加される var b1 = 'b1'; // 各変数の値を確認する。 // また、各変数がwindowオブジェクトのプロパティと // なることを確認する。 var t = 'a0:' + a0 + '<br />'; t = t + 'window.a0:' + window.a0 + '<br />'; t = t + 'a1:' + a1 + '<br />'; t = t + 'window.a1:' + window.a1 + '<br />'; t = t + 'b0:' + b0 + '<br />'; t = t + 'window.b0:' + window.b0 + '<br />'; t = t + 'b1:' + b1 + '<br />'; t = t + 'window.b1:' + window.b1 + '<br />'; document.getElementById('log').innerHTML = t; </script> </body> </html>
実行結果は次のようになります。varを使って宣言した変数は初期化されていないと、undefinedとなります。
a0:a0 window.a0:a0 a1:a1 window.a1:a1 b0:undefined window.b0:undefined b1:b1 window.b1:b1
もう少し掘り下げてみよう。JavaScriptでは関数もオブジェクトであることと、グローバル変数はwindowオブジェクトのプロパティとなることを考えると、グローバル関数についての理解を深めることができる。
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>setInterval sample 1</title> </head> <body> <div id="log" style="position:absolute;"></div><br /> <script> var t = 'f0:' + f0() + '<br />'; t = t + 'window.f0:' + window.f0() + '<br />'; function f0() { return 'f0'; } // function f0() {} と書くことは下記と同じだと考えて // よいだろう。 // window.f0 = function() { } // t = t + 'window.f1:' + window.f1() + '<br />'; // window.f1はプロパティなので、初期化されていないと // 参照できないので、上の文はコメントをはずすとエラー window.f1 = function () { return 'f1'; } t = t + 'window.f1:' + window.f1() + '<br />'; // f1はwindowオブジェクトのメソッドとなる t = t + 'f1:' + f1() + '<br />'; // 変数f2_a を宣言せずに下記関数を書くとエラーになる // function f2() { // return f2_a; // } function f2() { f2_a = 'f2_a'; return f2_a; } t = t + 'f2:' + f2() + '<br />'; t = t + 'window.f2:' + window.f2() + '<br />'; // 関数f2内でvarをつけずに初期化した変数f2_aは // windowオブジェクトのプロパティとなるので、ここで // 参照できる t = t + 'f2_a:' + f2_a + '<br />'; t = t + 'window.f2_a:' + window.f2_a + '<br />'; // f2()、f2_aについては下記と同じと考えてよい // var f2_a; // function f2() { // f2_a = 'f2_a'; // return f2_a; // } // 関数f3内でvarをつけずに初期化する変数f3_aに // ついて、宣言する場所を変えると、f3()を実行する // とエラー // t = t + 'window.f3_a:' + window.f3_a // もエラーになる function f3() { return f3_a; f3_a = 'f3_a'; } // 関数f4内でvarをつけて変数を用意すると、これは // 関数f4オブジェクトのプロパティとなる。 function f4() { var f4_a; return f4_a; } // f4_a は初期化されていないのでundefinedとなる t = t + 'f4():' + f4() + '<br />'; t = t + 'f4.f4_a:' + f4.f4_a + '<br />'; t = t + 'window.f4.f4_a:' + window.f4.f4_a + '<br />'; // 関数f5内でvarをつけて変数を用意すると、f5のプロパティ // になるので、どこで宣言しても良い。 function f5() { return f5_a; var f5_a; } // f5_aは初期化されていないのでundefinedとなる t = t + 'f5():' + f5() + '<br />'; t = t + 'f5.f5_a:' + f5.f5_a + '<br />'; t = t + 'window.f5.f5_a:' + window.f5.f5_a + '<br />'; // 関数f6内でvarをつけて変数を用意すると、f6のプロパティ // になるので、どこで宣言しても良い。 function f6() { var f6_a = 'f6_a'; return f6_a; } t = t + 'f6():' + f6() + '<br />'; // f6.f6_a は参照できるが、関数を実行しているわけではないので // f6_a = 'f6_a'; は実行されずに undefinedとなる。 t = t + 'f6.f6_a:' + f6.f6_a + '<br />'; t = t + 'window.f6.f6_a:' + window.f6.f6_a + '<br />'; // 関数f7内でvarをつけて変数を用意すると、f7のプロパティ // になるので、どこで宣言しても良い。 function f7() { return f7_a; var f7_a = 'f7_a'; } // f7_a = 'f7_a'; は実行されないのでundefinedとなる t = t + 'f7():' + f7() + '<br />'; t = t + 'f7.f7_a:' + f7.f7_a + '<br />'; t = t + 'window.f7.f7_a:' + window.f7.f7_a + '<br />'; // f7, f7_aについては下記と同じと考えてよい // function f7() { // var f7_a; // return f7_a; // f6_a = 'f7_a'; // } document.getElementById('log').innerHTML = t; </script> </body> </html>
実行結果は次のようになります。
f0:f0 window.f0:f0 window.f1:f1 f1:f1 f2:f2_a window.f2:f2_a f2_a:f2_a window.f2_a:f2_a f4():undefined f4.f4_a:undefined window.f4.f4_a:undefined f5():undefined f5.f5_a:undefined window.f5.f5_a:undefined f6():f6_a f6.f6_a:undefined window.f6.f6_a:undefined f7():undefined f7.f7_a:undefined window.f7.f7_a:undefined
JavaScriptについては、下記の書籍の参考になるでしょう。
プログラミング言語一般については、下記が参考になるでしょう。
- クラスベースのオブジェクト指向プログラミング言語の基礎を学ぶには … 改訂版 基礎Java(CD-ROM付) (IMPRESS KISO SERIES)
- クラスベースのオブジェクト指向プログラミング言語を学ぶには … プログラミング言語Java (The Java Series)
- 関数型プログラミング言語を学ぶには … Scalaスケーラブルプログラミング第2版
- プログラミング言語の理論を学には … プログラミング言語の基礎概念 (ライブラリ情報学コア・テキスト)