遅延委譲のお話
仕事でActionScriptごりごり書いてる時にちょっと必要に迫られて試してみたら、当たり前のようで当たり前じゃない盲点みたいな仕様はっけーん。
Function.apply, Function.call と setTimeout, setInterval が同時に使えない!
ユーティリティなメソッドで特定のムービーを遅延制御したかったんですが、あえなく撃沈。
Function.apply もれっきとしたメソッドだし、返り値を見ても setTimeout による登録が失敗したということではなさそうなのだけれど、内部的にスコープ処理がずれるのか一切実行されません。
たとえば以下のコード
function hoge( str1, str2 ){
trace( this + ": " + str1 + "," + str2 );
}
setTimeout( hoge.apply, 1000, this, ["Hello", "world"] );
setTimeout によって1秒後に
hoge.apply( this, ["Hello", "world"] );
が実行されることを期待してしまうのですが、上記の通り動きません。
このままでは埒が明かないので、上記のコードに加えてプロキシ委譲メソッドを用意します。
function proxyapply( func, target, args ){
func.apply( target, args );
}
setTimeout( proxyapply, 1000, hoge, this, ["Hello", "world"] );
こうすると、1秒後に
proxyapply( hoge, this, ["Hello", "world"] );
が実行され、結果
hoge.apply( this, ["Hello", "world"] );
が実行されます。
こうして遅延制御がうまくいきました、めでたしめでたしー
つか、これバグ? 仕様? バグという名の仕様?



コメント
Function.applyにFunction.applyが使えないのが原因だと思います。
hoge.apply(this, ["Hello", "world"]); // 動く
hoge.apply.apply(this, [this, ["Hello", "world"]]); // 動かない
内部でFunction.applyを使ってる関数に共通の問題ですね。(setTimeoutもそのひとつ)
投稿者: key | 2006年09月13日 12:58
>keyさん
ところがどっこい、使えますよ。
ここらへん、スコープの概念勉強してる人には鬼門だろうなあ。
投稿者: void | 2006年09月13日 14:27
間違えてthisを渡してましたorz
じゃあsetTimeout特有ですね。なんでなんだろう。
投稿者: key | 2006年09月14日 00:58