try catchでスコープが可能!?
AS3ではブロック単位のスコープは無くて、スコープが欲しい場合は、関数クロージャでくくったりする。でもそれ以外にも方法があったらしいね。
偶然にもtry catchでもスコープがあることを発見した。
なんだこれ?
package { import flash.display.Sprite; import flash.text.TextField; public class Main extends Sprite { public function Main():void { var xs:Array = []; try { throw 0; } catch (i:int) { for (; i < 5; i++ ) { xs.push(i); } } var sum:int = 0; try { throw 0; } catch (i:int) { for (; i < xs.length; i++ ) { sum += xs[i]; } } var tf:TextField = new TextField(); addChild(tf); tf.text = "sum" + sum; //trace(i);//コンパイルエラー } } }
http://wonderfl.net/code/47bb13e129e7eee92a0a556bbe430b78bb8cb29d#251374
iに注目。
catch(i:int)で宣言しているiのスコープはcatchの中になっているっぽい。
つまりcatchの外からはiは見えない。
何でこうなるかはわかんない。仕様なのか?バグなのか?
ひとまずこれで、これで関数内でスコープを自由自在に使いこなすことが出来るね!
...ってことにはならない。
そもそも例外を例外以外で使おうとするなんて、問題外。
可読性めっちゃ悪いし。
例えば、スコープの付いた変数を2個定義しただけでも、
try { throw 0; } catch (i:int) { try { throw 0; } catch (j:int) { for (i=0; i < 5; i++ ) { for (j=0; j < 5; j++ ) { trace(i, j); } } } }
と、ネストがひどい。
面白い機能だけど、くれぐれも遊び以外では使わないように!
追記
どうやらこれはECMAScripの仕様らしいです。
ECMA262規格で決められた仕様です。AS3はECMA262の拡張言語なのでECMAの仕様は踏襲していると思います。JavaScriptも同様だけど、これが正しく実装されていない処理系もあったりします(特にJScript)。