|
Flash CS4 のリソース |
関数のスコープ関数のスコープは、プログラム内の関数を呼び出すことができる場所だけではなく、関数がアクセスできる定義も決定します。変数識別子に適用される同じスコープの規則が関数識別子にも適用されます。 グローバルスコープで宣言された関数は、コード全体で使用することができます。 例えば、ActionScript 3.0 には、isNaN()、parseInt() などのコード内のどこでも使用できるグローバル関数があります。別の関数内で宣言された、ネストされた関数は、関数が宣言されている関数内のどの場所でも使用できます。 スコープチェーン関数が実行を開始するたびに、多数のオブジェクトおよびプロパティが作成されます。 最初に、アクティベーションオブジェクトという特別なオブジェクトが作成され、そこには関数本体で宣言されるパラメータとローカル変数または関数が格納されます。アクティベーションオブジェクトは内部メカニズムであるため、そこに直接アクセスすることはできません。 次に、スコープチェーンが作成され、そこには Flash Player または Adobe AIR によって識別子宣言の有無がチェックされるオブジェクトが列挙されたリストが含まれます。実行されるどの関数にも、内部プロパティに格納されるスコープチェーンがあります。 ネストされた関数の場合は、スコープチェーンはそのアクティベーションオブジェクトから始まり、その後に親関数のアクティベーションオブジェクトが続きます。このように、スコープチェーンはグローバルオブジェクトに達するまで続きます。 グローバルオブジェクトは、ActionScript プログラムが起動すると作成され、すべてのグローバル変数および関数を含みます。 関数クロージャ関数クロージャは、関数の静的なスナップショットとそのレキシカル環境を含むオブジェクトです。関数のレキシカル環境には、関数のスコープチェーン内のすべての変数、プロパティ、メソッド、およびオブジェクトがその値と共に含まれます。関数クロージャは、オブジェクトまたはクラスとは別に、関数が実行されるたびに作成されます。 関数クロージャはその関数クロージャが定義されたスコープを保持することから、関数がパラメータまたは戻り値として別のスコープに渡されると興味深い結果が生まれます。 例えば、次のコードは 2 つの関数を作成します。作成される関数の foo() は、矩形の面積を計算する rectArea() という名前のネストされた関数を返し、bar() は、foo() を呼び出し、myProduct という名前の変数に返された関数クロージャを格納します。bar() 関数が独自のローカル変数 x(値 2 を持つ)を定義する場合でも、関数クロージャ myProduct() が呼び出されると、関数 foo() で定義された変数 x(値 40 を持つ)を保持します。このため、bar() 関数は値 8 ではなく、値 160 を返します。 function foo():Function
{
var x:int = 40;
function rectArea(y:int):int // function closure defined
{
return x * y
}
return rectArea;
}
function bar():void
{
var x:int = 2;
var y:int = 4;
var myProduct:Function = foo();
trace(myProduct(4)); // function closure called
}
bar(); // 160
メソッドは、そのメソッドが作成されたレキシカル環境に関する情報も維持するように動作します。 この特性が最も顕著なのは、メソッドがバインドメソッドを作成するそのインスタンスから抽出されるときです。 関数クロージャとバインドメソッドの主な違いは、バインドメソッドの this キーワードの値は常に最初に関連付けられたインスタンスを参照しますが、関数クロージャでは this キーワードの値が変更可能という点です。詳しくは、メソッドを参照してください。 |