Home > | , > いまさらDelegate.createを理解しようと思ったけれど、謎が深まった愛され系の俺

いまさらDelegate.createを理解しようと思ったけれど、謎が深まった愛され系の俺

  • 2008-05-25 (日) 3:18
  • ���̃G���g���[���͂Ăȃu�b�N�}�[�N�ɒlj�

長らくAS2でお世話になっているおまじない、Delegate.create。ただなんとなしに使うのではなく、そろそろ理解しようと思い調べてみました。

理解するためには2つ必要でした。

  1. argumentsオブジェクトの理解
  2. Functionクラスの理解

argumentsオブジェクトの理解

argumentsオブジェクトは引数オブジェクトのことです。アクセスするには配列演算子を用いますが、単なる配列とは異なるようです。

argumentsオブジェクトにはcallerとcalleeプロパティが存在します。

arguments.caller

現在実行中の関数を呼び出した関数への参照となります。関数オブジェクトはdynamicクラスなので、あとからいくらでもプロパティを追加できるので、実際に参照しているのかテストしてみましょう。

function firstStep(){
	secondStep();
}
firstStep._x = 1;

function secondStep(){
	trace(arguments.caller._x);
	arguments.caller._x++;
}
firstStep();   //1が出力される
firstStep();   //2が出力される
firstStep();   //3が出力される

arguments.callee

現在実行中の関数への参照となります。

Functionクラスの理解

Function.apply()

Function.apply(scope:Object, [argArray: Array ]) :Void

functionオブジェクトのthisを置き換えるのがこのapplyメソッド。 これをうまく使えばmc.onReleaseなどのthisが変わるめんどくささから解放されます。

以上を踏まえて、mx.utils.Delegate.create()では何をしているのかというと

まずはmx.utils.Delegate.create()のコードを見てみましょう。

static function create(obj:Object, func:Function):Function
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments);
	};

	f.target = obj;
	f.func = func;
	return f;
}
  1. functionオブジェクト(var f)を作成
  2. functionオブジェクトに匿名関数を参照させる
  3. functionオブジェクトはdynamicクラスなので、追加プロパティを作れる
    • scopeとなるobjectと関数を保持させる
  4. 匿名関数内で、arguments.calleeを使って、自身(現在の関数)を参照し、
    • 先ほど保持したscopeと関数を拾う。
    • func.apply()で意図したscopeにfuncを割り当てる(thisを変える)

だいたいこんな感じでした。しかしながら、func.apply()には同時に引数も渡せるはずです。なので、ちょっと付け足してみました。

static function createWithArgs(obj:Object, func:Function, args:Array):Function
{
	var f = function()
	{
		var target = arguments.callee.target;
		var func = arguments.callee.func;
		return func.apply(target, arguments.callee.args.concat()); //ここを追加
	};

	f.target = obj;
	f.func = func;
	f.args = args; //ここを追加
	return f;
}

applyメソッドの第2引数にarguments.callee.args.concat()を追加するとうまく引数を登録できます。 引数の配列となるargsはconcatしないとうまく動作しません。

このあたりがさっぱりわからなかったので、ググってみましたがめぼしいものは見つからずさらに謎の動作まで見つけてしまいました。

http://library.sfug.ch/trac/browser/trunk/doc/as2/examples/sfug_as2lib/ch/sfug/utils/Delegate.as

ここはarguments.shift()でscopeとfuncを定義してるあたりがおもしろいですね。concat(arguments)でさらにdelegateした後で呼び出したときの引数も定義しています。なぜargumentsが使えるのかがなんとなくでしかわからないので、完全なる理解にはしばらく時間がかかりそうです。

Home > | , > いまさらDelegate.createを理解しようと思ったけれど、謎が深まった愛され系の俺


Search
Feeds
Meta

Return to page top