関数パラメータ

ActionScript 3.0 は、ActionScript を初めて使用するプログラマには斬新な関数パラメータの機能を備えています。値または参照によってパラメータを渡す方法は、ほとんどのプログラマが使い慣れている方法ですが、arguments オブジェクトと ... (rest) パラメータは、多くのプログラマにとって初めての方法と思われます。

サブトピック

引数の値渡しと参照渡し
デフォルトのパラメータ値
arguments オブジェクト
...(rest) パラメータ

引数の値渡しと参照渡し

多くのプログラミング言語では、値渡しと参照渡しによるパラメータの受け渡しの違いを理解しておくことが重要です。この違いは、コードの設計方法に影響します。

値渡しとは、関数内で使用するためにパラメータの値がローカル変数にコピーされることです。参照渡しとは、実際の値ではなく、パラメータへの参照のみが渡されることです。実際の値がコピーされるのではなく、パラメータとして渡される、変数への参照が作成され、関数内で使用するためにローカル変数に割り当てられます。関数外の変数への参照では、ローカル変数は元の変数の値を変更する機能を提供します。

ActionScript 3.0 では、値はすべてオブジェクトとして格納されているため、すべてのパラメータは参照渡しです。しかし、Boolean、Number、int、uint、String などのプリミティブデータ型に属するオブジェクトには、値渡しのように動作する特別な演算子があります。たとえば、次のコードは、xParamyParam という 2 つの int 型パラメータを定義する passPrimitives() という関数を作成します。この 2 つのパラメータは、passPrimitives() 関数の本体内で宣言されるローカル変数に似ています。関数がパラメータ xValue および yValue で呼び出されると、パラメータ xParam および yParam は、xValueyValue で表される int オブジェクトへの参照で初期化されます。パラメータはプリミティブなので、値渡しのように動作します。xParamyParam は、初期状態では xValueyValue オブジェクトへの参照のみが含まれますが、関数本体内の変数の変更によりメモリ内に新しい値のコピーが生成されます。

function passPrimitives(xParam:int, yParam:int):void
{
    xParam++;
    yParam++;
    trace(xParam, yParam);
}

var xValue:int = 10;
var yValue:int = 15;
trace(xValue, yValue);          // 10 15
passPrimitives(xValue, yValue); // 11 16
trace(xValue, yValue);          // 10 15

passPrimitives() 関数内では、xParam および yParam の値はインクリメントされますが、最後の trace ステートメントに示されているように、これは xValue および yValue の値に影響を与えません。パラメータが変数 xValue および yValue と同じ名前である場合でも同じです。これは、関数内の xValue および yValue は関数の外部にある同じ名前の変数とは別に存在するメモリ内の新しい位置を参照するためです。

プリミティブデータ型に属さないその他すべてのオブジェクトは、常に参照によって渡され、元の変数の値を変更する機能を提供します。たとえば、次のコードは、2 つのプロパティ x および y を持つ objVar というオブジェクトを作成します。このオブジェクトは、passByRef() 関数にパラメータとして渡されます。オブジェクトはプリミティブ型ではないため、参照渡しで渡されるだけではなく、参照のままでもあります。つまり、関数内のパラメータを変更すると、関数の外側にあるオブジェクトのプロパティも影響を受けます。

function passByRef(objParam:Object):void
{
    objParam.x++;
    objParam.y++;
    trace(objParam.x, objParam.y);
}
var objVar:Object = {x:10, y:15};
trace(objVar.x, objVar.y); // 10 15
passByRef(objVar);         // 11 16
trace(objVar.x, objVar.y); // 11 16

objParam パラメータは、グローバル変数 objVar と同じオブジェクトを参照します。この例の trace ステートメントからもわかるように、objParam オブジェクトの x および y プロパティを変更すると、objVar オブジェクトにも反映されます。

デフォルトのパラメータ値

ActionScript 3.0 では、関数のデフォルトのパラメータ値を宣言する機能が新しく追加されました。デフォルトのパラメータ値を使用した関数の呼び出しでデフォルト値のパラメータが省略されると、そのパラメータの関数定義で指定された値が使用されます。デフォルト値のパラメータはすべてパラメータリストの末尾に配置する必要があります。デフォルト値として割り当てられた値はコンパイル時定数である必要があります。パラメータのデフォルト値が存在すると、そのパラメータは "オプションパラメータ" になります。デフォルト値を持たないパラメータは、"必須パラメータ" と見なされます。

たとえば、次のコードは、3 つのパラメータで関数を作成します。このうち、2 つのパラメータにはデフォルト値があります。パラメータ 1 つだけで関数を呼び出す場合、そのパラメータのデフォルト値が使用されます。

function defaultValues(x:int, y:int = 3, z:int = 5):void
{
    trace(x, y, z);
}
defaultValues(1); // 1 3 5

arguments オブジェクト

パラメータが関数に渡されると、arguments オブジェクトを使用して関数に渡されたパラメータについての情報にアクセスできます。arguments オブジェクトには、次のようないくつかの重要な側面があります。

メモ

 

パラメータが arguments という名前の場合、または ... (rest) パラメータを使用する場合、arguments オブジェクトは利用できません。

ActionScript 3.0 では、関数呼び出しで関数定義内で定義されているパラメータより多いパラメータを指定できますが、パラメータ数が必須パラメータ数より少ない場合は strict モードでコンパイルエラーが生成されます。arguments オブジェクトの配列を使用すると、関数に渡されるパラメータが関数定義内で定義されたかどうかに関わらず、このパラメータにアクセスできます。次の例では、arguments 配列と arguments.length プロパティを使用して、traceArgArray() 関数に渡されるすべてのパラメータをトレースします。

function traceArgArray(x:int):void
{
    for (var i:uint = 0; i < arguments.length; i++)
    {
        trace(arguments[i]);
    }
}

traceArgArray(1, 2, 3);

// 出力 : 
// 1
// 2
// 3

arguments.callee プロパティは、再帰を作成する場合に匿名関数でよく使用されます。このプロパティを使用すると、コードに柔軟性を持たせることができます。開発過程で再帰関数の名前が変更された場合でも、関数名ではなく arguments.callee を使用していれば、関数本体内の再帰呼び出しの変更について考慮する必要はありません。arguments.callee プロパティは、次の関数式で使用して再帰を有効にします。

var factorial:Function = function (x:uint)
{
    if(x == 0)
    {
        return 1;
    }
    else
    {
        return (x * arguments.callee(x - 1));
    }
}

trace(factorial(5)); // 120

関数宣言に ... (rest) パラメータを使用する場合は、arguments オブジェクトは利用できません。代わりに、宣言したパラメータ名を使用してパラメータにアクセスする必要があります。

ストリング "arguments" をパラメータ名として使用しないようにする必要があります。このストリングは arguments オブジェクトをシャドウするためです。たとえば、関数 traceArgArray()arguments パラメータが追加されるように記述し直されると、関数本体内の arguments への参照は、arguments オブジェクトではなく、このパラメータを参照します。次のコードは出力を作成しません。

function traceArgArray(x:int, arguments:int):void
{
    for (var i:uint = 0; i < arguments.length; i++)
    {
        trace(arguments[i]);
    }
}

traceArgArray(1, 2, 3);

// 出力なし

旧バージョンの ActionScript の arguments オブジェクトには、caller という名前のプロパティも含まれていました。これは、現在の関数を呼び出した関数への参照です。ActionScript 3.0 には caller プロパティはありませんが、呼び出し関数の参照が必要な場合は、それ自体を参照する特別なパラメータを渡すように呼び出し関数を変更することができます。

...(rest) パラメータ

ActionScript 3.0 は、...(rest) パラメータと呼ばれる新しいパラメータ宣言を導入しています。このパラメータを使用すると、任意の数のカンマ区切りのパラメータを受け入れる配列パラメータを指定できます。パラメータには、予約語ではない名前を指定することができます。このパラメータ宣言は、指定される最後のパラメータである必要があります。このパラメータを使用すると、arguments オブジェクトは使用できなくなります。... (rest) パラメータには arguments 配列および arguments.length プロパティと同じ機能がありますが、arguments.callee のような機能はありません。... (rest) パラメータを使用する前に、arguments.callee を使用する必要はありません。

次の例は、arguments オブジェクトの代わりに ... (rest) パラメータを使用して、traceArgArray() 関数を書き直したものです。

function traceArgArray(... args):void
{
    for (var i:uint = 0; i < args.length; i++)
    {
        trace(args[i]);
    }
}

traceArgArray(1, 2, 3);

// 出力 : 
// 1
// 2
// 3

... (rest) パラメータは、最後にパラメータとしてリストする限り、他のパラメータと共に使用することもできます。次の例は、最初のパラメータ x を int 型にし、2 つ目のパラメータとして ...(rest) パラメータを使用するように、traceArgArray() 関数を変更します。最初のパラメータは ...(rest) パラメータで作成された配列の一部でなくなっているので、出力は最初の値をスキップします。

function traceArgArray(x: int, ... args)
{
    for (var i:uint = 0; i < args.length; i++)
    {
        trace(args[i]);
    }
}

traceArgArray(1, 2, 3);

// 出力 : 
// 2
// 3

 

このページに新しいコメントが追加された場合に、電子メールでの通知を希望する。 | コメントレポート

現在のページ: http://livedocs.adobe.com/flash/9.0_jp/main/00000055.html