変数のスコープとは、レキシカル参照によって変数にアクセスできるコードの範囲です。グローバル変数は、コードのすべての範囲で定義される変数で、ローカル変数は、コードの一部分でのみ定義される変数です。ActionScript 3.0 では、変数には、常にその変数が宣言された関数またはクラスのスコープが割り当てられます。 グローバル変数は、関数またはクラスの定義の外部で定義する変数です。 例えば、次のコードは、関数の外部で宣言して、グローバル変数 strGlobal を作成します。この例では、グローバル変数は関数定義の内部および外部の両方で利用できることを示します。
var strGlobal:String = "Global";
function scopeTest()
{
trace(strGlobal); // Global
}
scopeTest();
trace(strGlobal); // Global
ローカル変数を宣言するには、関数定義内で変数を宣言します。 ローカル変数を定義できるコードの最小範囲が関数定義です。 関数内で宣言されたローカル変数は、その関数内でのみ存在します。例えば、変数 str2 を関数 localScope() の中で宣言すると、この変数は関数の外部では利用できません。
function localScope()
{
var strLocal:String = "local";
}
localScope();
trace(strLocal); // error because strLocal is not defined globally
ローカル変数に使用した変数名がグローバル変数として宣言されている場合、ローカル変数がスコープ内にある間は、ローカル定義がグローバル定義を非表示に(シャドウ)します。ただし、グローバル変数は関数の外でも存在しています。例えば、次のコードは、グローバルストリング変数 str1 を作成した後、同じ名前のローカル変数を scopeTest() 関数内に作成します。関数内の trace ステートメントはこの変数のローカル値を出力しますが、関数の外にある trace ステートメントはこの変数のグローバル値を出力します。
var str1:String = "Global";
function scopeTest ()
{
var str1:String = "Local";
trace(str1); // Local
}
scopeTest();
trace(str1); // Global
C++ や Java の変数とは異なり、ActionScript の変数にはブロックレベルのスコープはありません。 コードブロックは、左中括弧({)と右中括弧(})で囲まれたステートメントのグループです。C++ や Java などのプログラミング言語では、コードブロック内で宣言された変数は、コードブロック外では利用できません。 このスコープ制限はブロックレベルのスコープと呼ばれますが、ActionScript にはありません。 コードブロック内で変数を宣言すると、変数はそのコードブロック内だけではなく、コードブロックが属する関数の他の部分でも利用できます。例えば、次の関数には様々なブロックスコープで定義された変数が含まれています。 すべての変数を関数全体で利用できます。
function blockTest (testArray:Array)
{
var numElements:int = testArray.length;
if (numElements > 0)
{
var elemStr:String = "Element #";
for (var i:int = 0; i < numElements; i++)
{
var valueStr:String = i + ": " + testArray[i];
trace(elemStr + valueStr);
}
trace(elemStr, valueStr, i); // all still defined
}
trace(elemStr, valueStr, i); // all defined if numElements > 0
}
blockTest(["Earth", "Moon", "Sun"]);
ブロックレベルのスコープが存在しないので、関数が終了する前に変数が宣言されている限り、宣言前の位置で変数に対して読み込み、書き込みを行うことができます。これは、コンパイラーによりすべての変数宣言が関数のトップレベルに移動されるホイストと呼ばれる手法によるものです。例えば、num 変数が宣言される前に num 変数に最初の trace() 関数が実行される次のコードも、コンパイルは問題なく行われます。
trace(num); // NaN
var num:Number = 10;
trace(num); // 10
しかし、コンパイラーは代入ステートメントをホイストしません。 このため、num の最初の trace() は数値データ型の変数のデフォルト値である NaN(非数)を返します。したがって、次の例に示すように、変数が宣言される前でも変数に値を割り当てることができます。
num = 5;
trace(num); // 5
var num:Number = 10;
trace(num); // 10