feb19.jp

Nobuhiro Takahashi
Designer / Engineer

Function.call()の使い道

Function.call()の使い道

知ってました?プログラミングにおけるものすごい基本的なことだったのかもしれないのですけど、こんな便利なことができるのです。

Test.as

package {
	public class Test {
		private var callback;
		public function Test(func){
			callback = func;
			init();
		}
		private function init() {
			callback.call(this);
		}
	}
}

タイムラインアクション

var test = new Test(onInit);
function onInit() {
	trace("onInit");
}

これを実行すると、TestクラスにonInit()が渡されて、callback.call(this)したときにonInit()が呼ばれる、という寸法。このとき、thisは、このクラスのインスタンスを生成したスコープ、つまりタイムラインアクションのスコープを指します。(違いました)

これで何が便利かっていうと、たとえばTweenerを使っている方は分かると思うのですが、onCompleteっていうプロパティに何か任意の関数を書くと、その関数を呼ぶことができますよね。そういう書き方、処理を作ることができる、ということです。たとえばMotionTypographyなんていうクラスを作って、それが終わった時に何か関数を呼び出す、っていうことができます。

EventDispatcherを使えばできることなんだけど、これはよりスマートな気がします。

なんてたって、EventDispatcherでは引数を渡すっていうとき、比較的複雑な処理が必要になるけど(Eventを継承するとか)、これならcallback.call(this, "hogehoge")とか、第二引数以降に引数となるものを入れてやればいいだけ。

何かしらのデメリットがあるんだろうけど(個人的にはガベージコレクション的に不安な気がします)、使いどころによってはすごく便利そうなので、久しぶりにメモってみました。

####

追記:

リファレンスのFunction.call()の意味がよくわからなかったのだけど、もう一度今読んだら意味がわかりました。要は、function.call(this)って、function()と同じ意味なのね。明示的にスコープを指定してやりたいときとかだけ使える、と。なんじゃそりゃー!大発見だと浮かれていた自分が恥ずかしい。まぁこれも成長、ということで。

ってことはいちいちEventDispatcherを使うっていう説明すらも恥ずかしいのかも。はぁ。とりあえず上のTest.asはこう書き直せます。

package {
	public class Test {
		private var callback;
		public function Test(func){
			callback = func
			init();
		}
		private function init() {
			callback();
		}
	}
}

うーん、こちらのほうが美しいですね。

Tweet Share Bookmark

Navigation

prev: ゴールデンスランバー/伊坂幸太郎
next: 続・Function.call()の使い道

Recently Entries