4 章 変数
4.2 変数の宣言
- 変数は必ず var で宣言する。宣言せずに値を代入した場合、その変数はグローバル変数になる。
- var で変数の初期値を設定しなかった場合は値が代入されるまで undefined になる。
- var で宣言された変数は永続され、delete 演算子で削除できない。
4.3 変数のスコープ
- グローバル変数のスコープはプログラム全体。
- ローカル変数のスコープはその変数が宣言された関数の中。
- 関数の中にグローバル変数と同じ名前のローカル変数があった場合はローカル変数が優先され、グローバル変数は隠される。
var scope = "global"; // グローバル変数
function checkScope() {
var scope = "local"; // ローカル変数
alert(scope);
}
checkScope(); // "local"
alert(scope); // "global"
scope = "global"; // グローバル変数
function checkScope() {
scope = "local"; // グローバル変数の値を変更
}
checkScope();
alert(scope); // "local"
var scope = "global";
function checkScope() {
alert(scope); // "global" ではなく undefined
var scope = "local";
alert(scope); // "local"
}
4.3.1 ブロックレベルのスコープはない
- ある関数で宣言された変数は、どのブロックで宣言されたのにかかわらず関数全体で有効である。
// i, j, k は scope 関数内で有効である
function scope() {
var i = 0;
for(var j = 0; j < 5; j++) {
document.write(j);
for(var k = 0; k < 5; k++) {
document.write(k);
}
}
}
4.5 ガーベジコレクション
- JavaScript インタプリタは、オブジェクトが不要になったと判定したら、オブジェクトが使用していたメモリを解放する。
4.6 プロパティと変数は違うのか
- オブジェクトのプロパティと変数は基本的に同じである。
4.6.1 グローバルオブジェクト
- JavaScript インタプリタは、コードの実行前にグローバルオブジェクトを生成する。
- グローバル変数とはグローバルオブジェクトのプロパティである。
- トップレベルコードでは、this はグローバルオブジェクトを参照する。
- クライアントサイド JavaScript でのグローバルオブジェクトは Window オブジェクトである。
4.6.2 ローカル変数は Call オブジェクトのプロパティ
- ローカル変数とは Call オブジェクトのプロパティである。
4.6.3 JavaScript の実行コンテキスト
- JavaScript インタプリタは個々の関数を実行するたびに、新しい実行コンテキストを生成する。
- 関数外部のコードの実行コンテキストでは、グローバルオブジェクトが変数定義に使用される。
- 関数内部のコードの実行コンテキストでは、Call オブジェクトが変数定義に使用される。
- 実装によっては、複数のグローバル実行コンテキストが認められている場合がある(クライアントサイド JavaScript で、ウィンドウがフレームで分割されている場合など)。
- 複数のグローバル実行コンテキスト間で相互に参照できるが、これはセキュリティ上の脅威になりうる。
4.7 変数のスコープの再検討
- 実行コンテキストには、それぞれのコンテキスト毎にスコープチェーンがある。
- スコープチェーンとは、グローバルオブジェクトや Call オブジェクトを並べたもの。
- 変数 x の値を探す時は、スコープチェーンの先頭のオブジェクトから x という名前のプロパティがあるかどうかを確かめる。
- 無ければ次のオブジェクトで探索を続け、見つかるまで探索する。
- 全てのオブジェクトでそのプロパティが存在しない場合は undefined になる。
- 下記のコードで g() 関数内で変数 x の値を探す場合、まず g() の Call オブジェクトのプロパティを探し、無ければ f() の Call オブジェクト、グローバルオブジェクトの順に探索し、グローバルオブジェクトのプロパティ x の値を返す。
var x = 1;
function f() {
var y = 2;
function g() {
var z = 3;
alert(x);
}
g();
}
f();