関数はスクリプト・ローカル
関数はスクリプト間で影響を与えない。同じ関数名を異なるスクリプトで用いても干渉しない。
以下のコードのうち外部スクリプトの内容は、それより上の二つのスクリプトの内容と同じ。スクリプトごとにmain()関数を実行しているが、それぞれのスクリプトで定義されたmain()関数が実行され、エラーや干渉は起きない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<script> main(); function main() { console.log( "First main() function" ); } </script> <script> main(); function main() { console.log( "Second main() function" ); } </script> <script src="third_main_function.js"> </script> |
グローバル変数は干渉
以下のコードは、スクリプト間のグローバル変数の挙動を示している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<script> var grovalVariable="global"; main(); function main() { console.log( grovalVariable ); } </script> <script> main(); function main() { console.log( grovalVariable ); } </script> <script> var grovalVariable = "overwritten" main(); function main() { console.log( grovalVariable ); } </script> |
上記コードの実行結果は以下のとおり。
1 2 3 |
global global overwritten |
- あるスクリプトでグローバル定義された変数は、それ以後のスクリプトに残される
- それ以後のスクリプトで、重ねてvar定義は可能で、その後はそれ以降の定義による
外部ファイルの注意点
クラスなどの資源を共有化するために、スクリプトを外部ファイルとする場合の注意点。
- 読み込みと実行
- head要素内でスクリプトファイルを読み込む場合、script要素を記述した順番に読み込まれる
- スクリプトファイルが読み込まれた時点で実行される
- グローバル変数
- グローバル変数を定義していた場合、スクリプトファイル読み込み時に定義される
- 同じグローバル変数を異なるファイルで重複定義した場合、最後に読み込まれたスクリプトの定義結果が反映される(変数の重複宣言を参照)
- クラス
- ローカルなインスタンス名は同じ名前でも干渉しない
- グローバルなインスタンスで重複定義されたオブジェクトは、最後に定義されたものが残る
以下に、クラス定義ファイルとインスタンス定義ファイルを別ファイルに分けた例を示す。
【HTMLファイル】
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<!DOCTYPE html> <html lang="ja"> <head> <script src="myclass.js"></script> <script src="instance1.js"></script> <script src="instance2.js"></script> </head> <body> <input type="button" value="Instance 1" onclick="instance1()"><br> <input type="button" value="Instance 2" onclick="instance2()"> </body> </html> |
【クラス定義ファイル】
1 2 3 |
function MyClass( name ) { this.name = name; } |
【インスタンス定義ファイル】
1 2 3 4 5 6 7 8 9 10 |
var globalVariable = 1; var globalInstance = new MyClass( "Global 1" ); function instance1() { var localInstance = new MyClass( "Local 1" ); console.log( globalVariable ); console.log( globalInstance.name ); console.log( localInstance.name ); } |
【別のインスタンス定義ファイル】
1 2 3 4 5 6 7 8 9 10 |
var globalVariable = 2; var globalInstance = new MyClass( "Global 2" ); function instance2() { var localInstance = new MyClass( "Local 2" ); console.log( globalVariable ); console.log( globalInstance.name ); console.log( localInstance.name ); } |
上記の実行結果と挙動は以下の通り。
1 2 3 4 5 6 7 8 |
("Instance 1"ボタンを押下) 2 Global 2 Local 1 ("Instance 2"ボタンを押下) 2 Global 2 Local 2 |
- head要素で3つのjsファイルが読み込まれる
- 読み込まれた時点で、グローバルな変数とオブジェクトが定義される
- 以降、ボタンを押すごとに、それぞれの関数でローカルな変数とオブジェクトが定義・表示される
- グローバルな変数・オブジェクトについては、最後に定義されたinstance2.jsの定義内容
変数、オブジェクトとも、グローバル・スコープのものについては、head要素内で最後に読み込まれたinstance2.jsの内容が保持される。読み込み順を入れ替えて最後にinstance1.jsを置くと、結果も変化する。