サイトトップ

Director Flash 書籍 業務内容 プロフィール

Macromedia Flash非公式テクニカルノート

名前のない関数(匿名関数/関数リテラル)

ID: FN0108016 Product: Flash

Platform: All
Version: 5.0 and above

名前のない関数
「匿名関数」あるいは「関数リテラル」とも呼ばれます。関数名を使わずに、式のかたちで記述します[*1]。その他の記述の仕方は、関数名を記述しないことを除いて、通常のfunctionアクションによる関数定義と同様です。なお、Flash 8オンラインヘルプ[ActionScript 2.0リファレンスガイド] > [ActionScript言語エレメント] > [ステートメント] > [functionステートメント]も、併せてご参照ください。

[*1] Flash 5の[アクション]パネルで[ノーマルモード]を選択すると、すべてのステートメントが1行で表示されてしまいます。MX以降では、この点は改善されました。

Flash MX 2004でfunctionの戻り値に型指定をして、[自動フォーマット]をすると、型指定がクリアされます。Flash 8では、この問題が解決されました。

シンタックス
ActionScript 1.0:
function ([引数0, 引数1, ... 引数N]) {
  ステートメント;
};

ActionScript 2.0:
function ([引数0:データ型, 引数1:データ型, ... 引数N:データ型]):データ型 {
  ステートメント;
};

引数
引数   オプション。functionに渡す任意の値を、変数として指定します。

ステートメント   functionの本文を構成するひとつ以上のステートメントです。

説明
関数名を指定しませんので、変数やプロパティに設定したうえで実行します。一度しか使わない関数のほか、ActionScript 1.0のクラス定義におけるメソッドや、イベントハンドラメソッドを始めとするインスタンスへのコールバック関数定義に使われます。また、グローバル(_global)にfunctionを定義する場合にも用いられます。通常のユーザー定義関数では、関数リテラルをあえて使わなければならない場面というのは、それほど多くはないでしょう。

通常のfunction定義と異なり、変数(あるいはメソッド)に名前のない関数を定義した後のステートメントからでないとその呼出し(実行)ができない点に注意が必要です。名前のない関数のfunctionブロック{}の後には、セミコロン;をつけます。さらに、細かな違いとして、通常のfunctionを定義するとそのタイムラインに参照が保持されるのに対して、名前のない関数では直接変数あるいはメソッドにfunctionを設定するためタイムラインに関数自体の参照を残さないことが挙げられます。したがって、関数を設定した変数やプロパティ、イベントハンドラメソッドなどを削除すれば、関数はメモリから消え去ります。

なお、名前のない関数は、Flash 8以前では定義すると同時に呼出すことができません(Flash MXおよびMX 2004、Flash 8で確認)[*2]。その合理的な理由は考えにくく、JavaScriptでは動作するようです。しかし、Flash Professional 9 ActionScript 3.0 Previewでは、[Publish Settings]において[ActionScript version]に[ActionScript 3.0]を選択すると、呼出しが可能になります。

[*2] Flash 8でつぎのサンプルを実行すると、名前のない関数は呼出されません。関数呼出しの演算子()を削除すれば、関数への参照は正しく取得できます。Flash 9でActionScript 3.0を使うと、関数は正しく呼出され、戻り値が変数に格納されます。

var returnedValue:Number = function ():Number {
  trace("called");   // 出力されない
  return 1;
}();
trace(returnedValue);   // undefined

Player
Flash 5以降。

(スクリプトには原則としてActionScript 2.0の型指定を用いています)
つぎのスクリプト(スクリプト001)は、比較関数[*3]を関数リテラルで定義して,配列エレメントを数値の順でソートします。Array.sort()メソッドを実行し終わると、functionはメモリから消去されます。

スクリプト001■Array.sort()メソッドに関数リテラルで比較関数を指定

var my_array:Array = [30, 200, 4, 5, 1000];
trace(my_array.sort());   // [出力]: 1000,200,30,4,5
//比較関数を関数リテラルで定義
my_array.sort(function (a:Number, b:Number):Number {
  return ((a>b)-(a<b));
});
trace(my_array)   // [出力]: 4,5,30,200,1000;

以下のサンプル(スクリプト002)は、setInterval()関数にfunctionを関数リテラルで指定しています。1秒(1000ミリ秒)後に、引数で渡されたタイムラインのパスを出力すると、インターバルの設定をclearInterval()関数でクリアします。functionは、インターバルの設定とともにメモリから消去されます。

スクリプト002■setInterval()関数に関数リテラルでfunctionを指定

// フレームアクション
var nID:Number = setInterval(function (_mc:MovieClip):Void {
  trace(_mc);   // スクリプトを記述したタイムラインのパスが出力
  clearInterval(nID);
}, 1000, this);   // 引数としてタイムラインの参照(this)を渡す

つぎのフレームアクション(スクリプト003)は、MovieClip.onEnterFrameイベントハンドラメソッドに、名前のないfunctionを設定しています。スクリプトを記述したインスタンスを、毎フレーム10ピクセルのスピードで右に水平移動させます。

スクリプト003■MovieClip.onEnterFrameイベントハンドラメソッドに名前のないfunctionを設定

// MovieClip: 水平移動させるインスタンス
// フレームアクション
this.onEnterFrame = function() {
   _x += 10;
};

以下の例(スクリプト004)は、ふたつの指定した数値の間のランダムな整数を返す[*4]関数xRandomIntを、グローバル(_global)に定義します。グローバル関数ですので、ローカルやタイムラインに同名の関数がないかぎり、どのタイムラインからでもターゲットパスなしに呼出すことができます。

スクリプト004■ランダムな整数を返す関数をグローバルに定義

// フレームアクション
_global.xRandomInt = function(nMin:Number, nMax:Number):Number {
  // 第2パラメータnMaxが指定されていない場合の処理
  // nMaxが数値でないかNaNであれれば0を代入
  if (typeof (nMax) != "number" || isNaN(nMax)) {
    nMax = 0;
  }
  // 小さい方の値をnMinに大きい方の値をnMaxに設定
  if (nMin>nMax) {
    var nTemp:Number = nMin;
    nMin = nMax;
    nMax = nTemp;
  }
  // nMinからnMaxまでのランダムな整数を返す
  return Math.floor(Math.random()*(nMax-nMin+1))+nMin;
};
// メソッドのテスト例
trace(xRandomInt(1, 6));   // 1から6までのランダムな整数が出力
trace(xRandomInt(6, 1));   // 1から6までのランダムな整数が出力
trace(xRandomInt(6));   // 0から6までのランダムな整数が出力

つぎのスクリプト(スクリプト005)は、ActionScript 1.0でカスタムクラスMyMathを定義しています。そしてクラスには、指定したふたつの数値の間のランダムな整数を返す静的メソッドradiansToDegreesが、名前のないfunctionとして設定されています。

スクリプト005■ActionScript 1.0のカスタムクラスにランダムな整数を返す静的メソッドを定義

// フレームアクション
// MyMathクラスを定義(ActionScript 1.0)
function MyMath() {}
// ラジアンを度数に変換する[*5]静的メソッドradiansToDegreesを定義
MyMath.radiansToDegrees = function(nRadians) {
  return nRadians*180/Math.PI;
};
// メソッドのテスト例
trace(MyMath.radiansToDegrees(Math.PI));   // [出力]: 180


[*3] 比較関数を使ったソートにつきましては、Macromedia Flash TechNote「数字の配列を値順にソートしたい」をご参照ください。

[*4] 指定した値の範囲でランダムな整数を計算するスクリプトについて詳しくは,Macromedia TechNote「Math.random() でランダムな整数を取得する方法」をお読みください。

[*5] 度数とラジアンの関係は、Macromedia Flash TechNote「角度と座標の計算−Flash 5 の三角関数を使う」に解説があります。

_____

作成者: 野中文雄
更新日: 2006年8月21日 Flash 8およびFlash 9/ActionScript 3.0の情報を追加。
更新日: 2005年9月19日 本文の一部修正と注釈の追加・補正、および[例]のサンプルスクリプトは全面的に改訂・追加
更新日: 2004年8月22日 レイアウトの変更と字句の若干の修正、および関数定義時の実行に関する問題を追加
更新日: 2003年5月11日 MXに対応した修正および説明の補足など
更新日: 2002年8月5日 MacromediaテクニカルノートのURL改訂に伴うリンク再設定
更新日: 2001年8月23日 例で使用する比較関数をMacromediaテクニカルノートに合わせて修正
作成日: 2001年8月20日


Copyright © 2001-2006 Fumio Nonaka.  All rights reserved.