関数の呼び出し
関数を呼び出すには、識別子の後に括弧(
()
)を使用します。関数に渡す関数パラメーターを括弧で囲みます。 例えば、
trace()
関数は ActionScript 3.0 のトップレベルの関数です。
trace("Use trace to help debug your script");
関数をパラメーターなしで呼び出す場合、空の括弧のペアを使用する必要があります。 例えば、パラメーターを取らない
Math.random()
メソッドは、乱数を生成します。
var randomNum:Number = Math.random();
ステートメントと式の選択
原則として、式を使用する必要がある場合を除いて、function ステートメントを使用します。 function ステートメントは、関数式より簡潔で、strict モードと standard モードで一貫した使いやすさを提供します。
function ステートメントは、関数式を含む代入ステートメントより読みやすくなります。 function ステートメントを使用すると、コードが簡潔になり、
var
と
function
キーワードを両方使用する必要がある関数式よりわかりやすくなります。
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 "10";
}
function getProductName():String
{
return "Flash Player";
}
return (getProductName() + " " + getVersion());
}
trace(getNameAndVersion()); // Flash Player 10
ネストされた関数が外部コードに渡される場合、関数クロージャとして渡されます。つまり、関数が定義されるとき、スコープ内にある定義を保持します。 詳しくは、関数のスコープを参照してください。