ActionScript 3.0入門ノート CS4でタグ「function」が付けられているもの

(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 関数のネスティング(入れ子で定義する)も可能です。次の例はgetUser関数の中にgetID関数とgetName関数が定義されています

[:script:]関数の中に関数を入れ子で定義する
function getUser():Array { 
	var domain:String = "jq1";
    function getID():String { 
        return domain+"abc"; 
    } 
    function getName():String { 
        return "大重美幸"; 
    } 
    return ([getID(),getName()]); 
} 
//テスト
trace(getUser());//出力:jq1abc,大重美幸
 関数をネスティングする利点には、親関数getUser()のローカル変数の値をネストされた子関数getID()が利用できることがあります。このような形態を関数クロージャ(function closure)あるは関数閉包と呼びます。関数クロージャが他の関数に引数として渡されたり、ほかの関数から呼び出された場合にも内部のローカル変数の値は保持されます。

note
関数クロージャではthisを正しく理解して使う必要があります。
var a:int=1;
trace(this, this.a, a);//出力:[object MainTimeline] 1 1
function test():void {
	var a:int=2;
	trace(this, this.a, a);//出力:[object MainTimeline] 1 2
	closetest();
	function closetest():void {
		trace(this, this.a, a);//出力:[object global] undefined 2
	}
}
//テスト
test();
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 関数はFunctionクラスのインスタンスの値として扱うことができることから、他の変数に代入したり引数として渡すことができます。たとえば、次のようにheikin3関数を定義したとき、heikin3を変数myTest(データ型:Function)に代入することでheikin3()をmyTest()で実行できるようになります。

[:script:]関数を変数の値に入れて使う
//3つの値の平均を求める
function heikin3(a:Number, b:Number, c:Number):Number {
	var abc:Number = a+b+c;
	var ans:Number = abc/3;
	return ans;
}
//関数を変数に代入する
var myTest:Function = heikin3;
var ans:Number = myTest(10, 20, 30);
trace(ans); //出力:20
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 関数はFunctionクラスのインスタンスの値として扱うことができることから、他の変数に代入したり引数として渡すことができます。たとえば、次のようにheikin3関数を定義したとき、heikin3を変数myTest(データ型:Function)に代入することでheikin3()をmyTest()で実行できるようになります。

[:script:]関数を変数の値に入れて使う
//3つの値の平均を求める
function heikin3(a:Number, b:Number, c:Number):Number {
	var abc:Number = a+b+c;
	var ans:Number = abc/3;
	return ans;
}
//関数を変数に代入する
var myTest:Function = heikin3;
var ans:Number = myTest(10, 20, 30);
trace(ans); //出力:20
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 中上級者向けの内容になりますが、関数を定義する方法には関数式を使うやり方もあります。関数式でもfunctionを使って関数を定義しますが、関数名を指定しない点に注目してください。関数名がないことから関数式で定義した関数は匿名関数あるいは関数リテラルと呼ばれます。

関数式の書式:
var 変数:Function = function (引数:データ型, 引数:データ型, ...):戻す値のデータ型{
//実行するスクリプト
}

 次の匿名関数は引数の値を10倍した値を出力します。定義した匿名関数は、続く7行目で行っているように関数を代入した変数名にカッコを付けて、test(3)のように実行できます。

[:script:]値を10倍する匿名関数を定義する
var test:Function = function (a:Number):void{
	var ans:Number = a * 10;
	trace(ans);
};

//匿名関数を使う
test(3); //出力:30
 値を戻す匿名関数も定義できます。次の匿名関数は引数の値を10倍した値を返します。

[:script:]10倍した値を返す匿名関数を定義する
var test:Function = function (a:Number):Number{
	var ans:Number = a * 10;
	return ans;
};

var ans:Number = test(5);
trace(ans); //出力:50
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 中上級者向けの内容になりますが、関数を定義する方法には関数式を使うやり方もあります。関数式でもfunctionを使って関数を定義しますが、関数名を指定しない点に注目してください。関数名がないことから関数式で定義した関数は匿名関数あるいは関数リテラルと呼ばれます。

関数式の書式:
var 変数:Function = function (引数:データ型, 引数:データ型, ...):戻す値のデータ型{
//実行するスクリプト
}

 次の匿名関数は引数の値を10倍した値を出力します。定義した匿名関数は、続く7行目で行っているように関数を代入した変数名にカッコを付けて、test(3)のように実行できます。

[:script:]値を10倍する匿名関数を定義する
var test:Function = function (a:Number):void{
	var ans:Number = a * 10;
	trace(ans);
};

//匿名関数を使う
test(3); //出力:30
 値を戻す匿名関数も定義できます。次の匿名関数は引数の値を10倍した値を返します。

[:script:]10倍した値を返す匿名関数を定義する
var test:Function = function (a:Number):Number{
	var ans:Number = a * 10;
	return ans;
};

var ans:Number = test(5);
trace(ans); //出力:50
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 同一のタイムライン内では同名の変数は1個しか宣言することが許されません。つまり、たとえ異なるキーフレームのフレームアクションでも変数名が同じならばそれは同じ変数であり同じ値が入っています。これをグローバル変数と呼びます。
 ところが、メソッドや関数を定義するfunctionブロックの内側で変数を宣言したとき、その変数は個別のfunctionブロックの中だけで利用できる変数になります。これをローカル変数と呼びます。
 functionブロックの中と外で同名の変数が定義してあるとき、functionブロックの外の変数はグローバル変数になり、functionの中で宣言した変数はローカル変数になります。もちろん名前の重複エラーになることもありません。
 次の例では変数aをfunctionの外で宣言しています。この場合、test1()、test2()のfunction内も含めて同一タイムラインにおいて変数aは共通のグローバル変数になります。

note
ムービークリップのタイムラインで定義してあるグローバル変数の値は、ムービークリップのインスタンスごとに保存されます。

[:script:]functionブロックの外で宣言するグローバル変数a
//変数aの宣言
var a:int=100;

function test1():void{
	//変数aに1加算する
	a += 1;
	trace(a);
}

function test2():void{
	//変数aを2倍する
	a *= 2;
	trace(a);
}

//テスト
test1(); //出力:101
test2(); //出力:202
trace(a); //出力:202
 一方、次の例では変数aをfunctionブロックの外だけでなく、test1()のfunctionブロックの中でも宣言して使っています。このとき、続くテストの結果を見るとわかるように、test2()で参照している変数aはブロックの外で宣言している変数aと同じ変数ですが、test1()の中で宣言してある変数aは名前が同じでもtest1()の中だけの変数、すなわちローカル変数であることがわかります。

[:script:]test1()ではローカル変数aを宣言して使う
//変数aの宣言
var a:int=100;

function test1():void{
	//ローカル変数aの宣言
	var a:int=5;
	//ローカル変数aに1加算する
	a += 1;
	trace(a);
}

function test2():void{
	//変数aを2倍する
	a *= 2;
	trace(a);
}

//テスト
test1(); //出力:6
test2(); //出力:200
trace(a); //出力:200
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 関数は次のようにfunctionで定義し、returnで演算結果を戻します。値はfunctionを呼び出した位置に戻ります。関数では演算に使用する値を引数で受け取ることができます。
 引数で受け取る値のデータ型と関数で戻す値のデータ型を指定できます。データ型の指定は省略可能ですが、データ型を指定することでコンパイル時にデータ型の妥当性がチェックされます。
 メソッドと同様に関数定義はタイムラインのキーフレームで行いますが、関数を定義してあるキーフレームを再生していなくても、同じタイムラインであればどこからでもその関数を利用できます。同一のタイムラインで同名の関数を定義することはできません。

書式:
function 関数名(引数:データ型, 引数:データ型, ...):戻す値のデータ型{
//実行するステートメント
return 戻す値;
}

次のheikin3()は引数で与えられた3つの数値の平均を求めて返す関数です。

[:script:]3つの値の平均を求める
function heikin3(a:Number, b:Number, c:Number):Number {
	var abc:Number = a+b+c;
	var ans:Number = abc/3;
	return ans;
}	
 次の例がheikin3()を使って3教科の点数の平均を求めた場合です。ここに示すようにheikin3(kokugo, sugaku, eigo)を実行して得られた値が変数heikintenに入ります。heikin3()で戻る値のデータ型をNumberに指定しているので、変数heikintenのデータ型と一致します。

[:script:]3教科の平均点を求める
var kokugo:uint = 76;
var sugaku:uint = 62;
var eigo:uint = 70;
var heikinten:Number = heikin3(kokugo, sugaku, eigo);
trace(heikinten); //出力:69.33333333333333
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 returnを実行することでメソッドの中の残りの処理を中断できます。returnは関数の中で値を戻すためのステートメントですが、メソッドの中では戻す値を指定せずに使用します。
 次のtest()は引数aが0のときは処理を中断します。このスクリプトでは2行目で条件分岐のif文を使っています。これによりaの値が0のときだけ4行目のreturnが実行され、続く6行目が実行されずにtest()が終了します。aの値が0でないときはif文で囲った中が実行されずに6行目が実行されます。

[:script:]引数が0のとき処理を中断する
function test(a:int):void {
	if(a==0){
		trace("中断");
		return;
	}
	trace(10/a);
}

test(0);//出力:中断
test(5);//出力:2
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 引数の個数が決まっていない場合には、残りの引数を...restのように書いて変数restで受けることができます。restは変数名なので...vlist、...nokoriのように好きな変数名を使えます。引数の値は指定の変数に配列で入ります。
 次の例では引数はすべて変数vlistに配列で入ります。

[:script:]引数の個数を指定せず、すべて配列に入れる
function test(...vlist):void {
	//配列vlistの値を出力する
	trace(vlist);
}

//引数をテストする
test(10, 20, 30, 40);
//出力:10,20,30,40
 次の例では第1引数は変数aに入りますが、残りの引数はすべて変数restに配列で入ります。

[:script:]2個目以降の引数は配列に入れる
function test(a:String, ...rest):void {
	//引数の値を出力する
	trace(a);
	trace(rest);
}

//引数をテストする
test("色", "red", "green", "blue", "black");
 出力結果は次のようになります。変数aには"色"と入り、変数restには色の名前が配列で入ります。

出力結果:

red,green,blue,black
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 メソッドに引数を渡すことができます。引数にはデータ型を指定できます。次のスクリプトは、動かすインスタンスと移動距離を引数で指定できるようにmoveXメソッドを変更したものです。

[:script:]動かすインスタンスと距離を引数で指定する
//moveX()の定義
function moveX(mc:MovieClip, v:Number):void {
	mc.x = mc.x + v;
}

//moveX()を実行する
moveX(my_mc1, 150);
moveX(my_mc2, 200);
 このサンプルではmoveX()を2度実行しています。moveX(my_mc1, 150)ではmy_mc1を右へ150ピクセル移動させ、moveX(my_mc2, 200)ではmy_mc2を右へ200ピクセル移動させます。このように引数を使うことで同じような処理を1つのメソッドで実現できるようになります。
 メソッドに引数が指定してある場合、メソッドを実行する際に引数と同数の値を渡す必要があります。引数の個数が一致しない場合はエラーになります。また、引数のデータ型が一致しない場合もエラーになります。たとえば、次のようなケースではエラーになります。

[:script:]引数が一致せずにエラーになるケース
//moveX()の定義
function moveX(mc:MovieClip, v:Number):void {
	mc.x = mc.x + v;
}

//エラーになるケース
moveX(my_mc1);//引数の個数が合わない
moveX(my_mc2, 200, 15);//引数の個数が合わない
moveX("my_mc1", 200);//引数のデータ型が合わない

引数の省略と初期値
 メソッドの引数が省略されたときに初期値を指定することができます。引数に初期値を指定するには、「引数=初期値」のように指定します。次の例では引数a、bの初期値をそれぞれ1と10に設定しています。

[:script:]引数に初期値が設定してあるメソッド
function ab(a:int=1, b:int=10):void {
	trace(a+b);
}

//引数による結果の違いのテスト
ab();//出力:11
ab(5);//出力:15
ab(5,50);//出力:55
 引数を変えてテストした結果をみるとわかるように、初期値が設定してあれば引数の個数が不足してもエラーにはならず、省略した引数はその値に初期値が使用されます。  なお、引数に初期値が指定してあっても前の引数の値を省略することはできません。また、指定の引数の個数以上の引数を渡すとエラーになります。

[:script:]エラーになるケース
ab(, 30);//前の引数は省略できない
ab(5,6,7);//引数の個数が多い
 メソッドを定義する場合、複数の引数があるとき引数の省略は後ろから可能です。次の例では第2引数にのみ初期値を指定しているので、第2引数のみ省略可能になります。

[:script:]第2引数のみ省略可能
function ab(a:int, b:int=10):void {
	trace(a+b);
}

//引数による結果の違いのテスト
ab(5);//出力:15
ab(5,50);//出力:55

 次のように初期値を指定していない引数より前の引数に初期値を指定することはできません。

[:script:]前の変数の初期値だけ指定するとエラーになる
function ab(a:int=1, b:int):void {
	trace(a+b);
}

note関数の引数の値渡しと参照渡し」も参照してください。
(section01-03 フレームアクションのメソッド定義と関数定義から抜粋)

 スクリプトの中でよく利用する処理はfunctionを使ってメソッドとして定義することができます。メソッドでは処理に使用する値を引数で受け取ることができます。メソッドのデータ型は省略可能ですが、省略しない場合には必ずvoidを指定します。
 メソッド定義はタイムラインのキーフレームで行いますが、メソッドを定義してあるキーフレームを再生していなくても、同じタイムラインであればどこからでもそのメソッドを利用できます。同一のタイムラインで同名のメソッドを定義することはできません。

メソッドの書式:
function メソッド名(引数:データ型, 引数:データ型, ...):void{
//実行するスクリプト
}

 次のスクリプトはmy_mcを右へ200ピクセル移動させるmoveXメソッドを定義するスクリプトです。このメソッドには引数はありません。

[:script:]moveX()メソッドの定義
function moveX():void {
 my_mc.x = my_mc.x + 200;
}

 moveXメソッドはmoveX()で実行できます。

[:script:]moveX()の定義と実行
//moveX()の定義
function moveX():void {
	my_mc.x = my_mc.x + 200;
}	
	
//moveX()を実行する
moveX();
(section05-03 座標移動のアニメーションから抜粋)

 次のサンプルでは、トゥイーンアニメーションの関数を配列motionListに入れておき、トゥイーンが完了したならばmotionListから順に次の関数を取り出して実行します。トゥイーンの関数には右へトゥイーンするmoveRight()、左へトゥイーンするmoveLeft()、180度回転するturn()の3つの種類の関数があります。これを9行目で示すように[moveRight,turn,moveLeft,turn]の順でmotionListに入れます。そしてnextMotion()でmotionListから関数を順に取り出して実行していきます。36行目ではmotionListから取り出した関数は変数motionに入れていますが、motion()と実行することで取り出した関数を実行できます。

 トゥイーンアニメーションのそれぞれの関数では、実行したトゥイーンが完了したならばnextMotion()を呼び出すようにTweenEvent.MOTION_FINISHイベントのリスナー関数を登録します。moveRight()、moveLeft()、turn()で毎回新しくtwObjインスタンスを作成するので、そのつどにTweenEvent.MOTION_FINISHイベントのリスナー関数を登録しなければなりません。

fig05-03-04_shiji.jpgswfを試す

[:script:]複数のトゥイーンアニメーションを連続して再生する
まったく新しいAS3の世界!
694a.jpg
Adobe Flash CS4
詳細!ActionScript3.0入門ノート[完全改訂版](CD-ROM付)

楽しいActionScript。
新たなる1歩へと踏み出しましょう。
■内容は?→ 目次を見る
■評判は?→ 書評を読む
この本を書いたわけ

タグ

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

あわせて読みたいブログパーツ