変数のスコープとは、レキシカル参照によって変数にアクセスできるコードの範囲です。グローバル変数は、コードのすべての範囲で定義される変数で、ローカル変数は、コードの一部分でのみ定義される変数です。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