Adobe Flex 3 ヘルプ

基本的な関数の概念

このセクションでは、基本的な関数の定義と呼び出し方法について説明します。

サブトピック



呼び出し元の関数

関数を呼び出すには、識別子の後に括弧(())を使用します。関数に渡す関数パラメータを括弧で囲みます。例えば、trace() 関数は Flash Player API のトップレベル関数ですが、本マニュアルの様々な箇所で使用されています。

trace("Use trace to help debug your script");

パラメータのない関数を呼び出す場合は、空括弧を使用する必要があります。例えば、パラメータを取らない Math.random() メソッドは、乱数を生成します。

var randomNum:Number = Math.random();

独自の関数の定義

ActionScript 3.0 の関数を定義するには、function ステートメントを使用する方法と関数式を使用する方法の、2 つの方法があります。どちらの方法を選択するかは、プログラミングスタイルをより静的にするか動的にするかによって決まります。静的な、つまり strict モードのプログラミングの方を好む場合は、function ステートメントで関数を定義します。そうすることに特定の必要性がある場合は、関数式で関数を定義します。関数式は、動的、つまり standard モードのプログラミングでより頻繁に使用されます。

Function ステートメント

function ステートメントは、strict モードで関数を定義するのに適しています。function ステートメントは、function キーワードで始まり、その後に以下が続きます。

  • 関数の名前
  • 括弧で囲まれたカンマ区切りリストで指定されたパラメータ
  • 関数の本体、つまり関数が呼び出されると実行される、中括弧で囲まれた ActionScript コード

例えば、次のコードは、パラメータを定義する関数を作成し、ストリング "hello" をパラメータ値として使用して、関数を呼び出します。

function traceParameter(aParam:String)
{
    trace(aParam);
}

traceParameter("hello"); // hello

関数式

関数を宣言する 2 つ目の方法は、代入ステートメントに関数式を使用することです。関数式は、関数リテラルまたは匿名関数とも呼ばれます。これは、旧バージョンの ActionScript で広く使用されている、より冗長になる方法です。

関数式を使用した代入ステートメントは、var キーワードで始まり、その後に以下が続きます。

  • 関数の名前
  • コロン演算子(:
  • データ型を示すための Function クラス
  • 代入演算子(=
  • function キーワード
  • 括弧で囲まれたカンマ区切りリストで指定されたパラメータ
  • 関数の本体、つまり関数が呼び出されると実行される、中括弧で囲まれた ActionScript コード

例えば、次のコードは関数式を使用して traceParameter 関数を宣言します。

var traceParameter:Function = function (aParam:String)
{
    trace(aParam);
};
traceParameter("hello"); // hello

function ステートメントとは異なり、関数の名前を指定していないことに注意してください。関数式が function ステートメントと異なるもう 1 つの特徴は、関数式はステートメントではなく式であることです。つまり、function ステートメントのように、関数式はそれだけでは成立しません。関数式は、通常は代入ステートメントなど、ステートメントの一部としてのみ使用することができます。次の例は、配列エレメントに代入された関数式を示します。

var traceArray:Array = new Array();
traceArray[0] = function (aParam:String)
{
    trace(aParam);
};
traceArray[0]("hello");

ステートメントと式の選択

原則として、式を使用する必要がある場合を除いて、function ステートメントを使用します。function ステートメントは、関数式より簡潔で、strict モードと standard モードで一貫した使いやすさを提供します。

function ステートメントは、関数式を含む代入ステートメントより読みやすくなります。function ステートメントを使用すると、コードが簡潔になり、varfunction キーワードを両方使用する必要がある関数式よりわかりやすくなります。

function ステートメントは、2 つのコンパイラモードで一貫した使いやすさを提供します。つまり、strict モードおよび standard モードの両方でドットシンタックスを使用し、function ステートメントを使用して宣言されたメソッドを呼び出すことができます。これは、関数式を使用して宣言されたメソッドには必ずしも当てはまりません。例えば、次のコードは、2 つのメソッドで Example というクラスを定義します。関数式で宣言される methodExpression() と function ステートメントで宣言される methodStatement() です。strict モードでは、ドットシンタックスを使用して methodExpression() メソッドを呼び出すことはできません。

class Example
{
var methodExpression = function() {}
function methodStatement() {}
}

var myEx:Example = new Example();
myEx.methodExpression(); // error in strict mode; okay in standard mode
myEx.methodStatement(); // okay in strict and standard modes

関数式は、実行時、つまり動的なビヘイビアを中心にしたプログラミングに適しています。strict モードを使用し、関数式で宣言されるメソッドを呼び出す必要がある場合は、次の 2 つの方法のいずれかを使用することができます。1 つ目は、ドット(.)演算子ではなく、角括弧([])を使用してメソッドを呼び出す方法です。次のメソッドの呼び出しは、strict モードと standard モードの両方で成功します。

myExample["methodLiteral"]();

2 つ目は、クラス全体をダイナミッククラスとして宣言する方法です。この場合、ドット演算子を使用してメソッドを呼び出すことができますが、そのクラスのすべてのインスタンスで strict モードの一部の機能が犠牲になるという短所があります。例えば、ダイナミッククラスのインスタンスの未定義のプロパティにアクセスしようとした場合、コンパイラはエラーを生成しません。

関数式が便利な場合があります。関数式の一般的な使用法は、1 回だけ使用された後で破棄される関数に使用することです。また、一般的な使用法ではありませんが、関数をプロトタイププロパティに関連付けるために使用します。詳細については、プロトタイプオブジェクトを参照してください。

function ステートメントと関数式には、どちらを使用するかを選択する際に考慮する必要がある微妙な違いが 2 つあります。1 つ目の違いは、関数式は、メモリ管理およびガベージコレクションに関してオブジェクトとして単独で存在しません。つまり、配列エレメントやオブジェクトプロパティなどの別のオブジェクトに関数式を割り当てると、コード内にその関数式への唯一の参照が作成されます。関数式が関連付けられている配列またはオブジェクトがスコープ外に移動するか、使用できなくなった場合、関数式にアクセスできなくなります。配列またはオブジェクトが削除されると、関数式が使用するメモリはガベージコレクションの対象となります。つまり、メモリは解放されて他の目的に再利用されます。

次の例では、関数式の場合、関数式が割り当てられているプロパティが削除されると、関数が利用できなくなることを示します。クラス Test は動的です。つまり、関数式を保持する functionExp というプロパティを追加できます。functionExp() 関数は、ドット演算子を使用して呼び出すことができますが、functionExp プロパティが削除されると、関数にアクセスできなくなります。

dynamic class Test {}
var myTest:Test = new Test();

// function expression 
myTest.functionExp = function () { trace("Function expression") };
myTest.functionExp(); // Function expression
delete myTest.functionExp;
myTest.functionExp(); // error

その一方で、関数が最初に function ステートメントで定義された場合、関数はそのオブジェクトとして存在し、関連付けられているプロパティを削除しても存在します。delete 演算子はオブジェクトのプロパティに対してのみ動作するため、関数 stateFunc() 自体を削除するための呼び出しも動作しません。

dynamic class Test {}
var myTest:Test = new Test();

// function statement
function stateFunc() { trace("Function statement") }
myTest.statement = stateFunc;
myTest.statement(); // Function statement
delete myTest.statement;
delete stateFunc; // no effect
stateFunc();// Function statement
myTest.statement(); // error

function ステートメントと関数式の 2 つ目の違いは、function ステートメントは、関数ステートメントの前に現れるステートメント内を含む、定義されたスコープ全体で存在することです。対照的に、関数式はそれ以降のステートメントに対してのみ定義されます。例えば、次のコードは、scopeTest() 関数が定義される前に、その関数を正常に呼び出します。

statementTest(); // statementTest

function statementTest():void
{
    trace("statementTest");
}

関数式は、定義される前に使用することはできません。したがって、次のコードはランタイムエラーになります。

expressionTest(); // run-time error

var expressionTest:Function = function ()
{
    trace("expressionTest");
}

関数からの値の戻り

関数から値を返すには、return ステートメントの後に、返す式またはリテラル値を使用します。例えば、次のコードは、パラメータを表す式を返します。

function doubleNum(baseNum:int):int
{
    return (baseNum * 2);
}

return ステートメントは関数を終了するため、次のように、return ステートメントより下にあるステートメントは実行されません。

function doubleNum(baseNum:int):int {
    return (baseNum * 2);
    trace("after return"); // This trace statement will not be executed.
}

strict モードでは、戻り値の型を指定した場合、適切な型の値を返す必要があります。例えば、次のコードは、有効な値を返さないため、strict モードではエラーを生成します。

function doubleNum(baseNum:int):int
{
    trace("after return");
}

ネストされた関数

関数をネスト、つまり別の関数内で関数を宣言することができます。ネストされた関数は、関数への参照が外部コードに渡される場合を除いて、その親関数内でのみ使用できます。例えば、次のコードは getNameAndVersion() 関数内でネストされた関数を 2 つ宣言します。

function getNameAndVersion():String
{
    function getVersion():String
    {
        return "9";
    }
    function getProductName():String
    {
        return "Flash Player";
    }
    return (getProductName() + " " + getVersion());
}
trace(getNameAndVersion()); // Flash Player 9

ネストされた関数が外部コードに渡される場合、メソッドクロージャとして渡されます。つまり、関数が定義されるとき、スコープ内にある定義を保持します。詳細については、メソッドクロージャを参照してください。

 

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