どうも、先日初めてAS2を触ったプログラマのaragaです。

最近ActionScript2.0で作られた某サービスが突然動かなくなったので対応しましたが、AS2.0の挙動で不可解な点があったのでご報告します。

ExternalInterfaceを使ってJSと通信している機能において以下のようなことが起きました。

1.Numberを含む可変のプロパティをObjectにまとめてJSからSWFに渡していたところ、
Number型だったはずのプロパティがStringに変わっていた。
これにより

switch(object.number) { case 1: hoge(); break; ・・・ }

というswitch条件が全て当てはまらなくなっていた。

2.1と同じ変数をNumber型で型宣言している変数に代入していたが、Stringの挙動をしていた。
これにより

var flag:Number = object.number; if (flag) { //object.number==1の時に動く予定の処理 }

というif分が必ず条件に一致するようになった

この2つのバグより以下のことが考えられますので気をつけましょう。

1.JSまたはExternalInterfaceのobject型の仕様が変わった?
数ヶ月前まで、JSからNumber型として変数がわたってきていた訳ですが、
今回String型になっていたということは、ExternalInterfaceでobjectの変数はStringとみなされるようになったか、JSでNumberがStringになったかとにかくどちらかの仕様が変わった可能性があります。

2.AS2.0での型指定はコンパイル時以外意味が無い?
AS2において型指定をしても、コンパイル後はキャストをするでもエラーがでるでもなく、
型は関係なく代入されている可能性があります。
試しに

if (0) { trace("true"); } else { trace("false"); } if ("0") { trace("true"); } else { trace("false"); }

を試した結果はfalse、trueだったので型宣言は意味が無くStringが代入されていたと言って良いと思います。



では、どうしたらよいか。


どちらもAS2初心者の僕の推測にすぎないので間違っているかもしれませんが、
どちらも安心できる方法があります。

1.キャストする

var number:Number = Number(object.number);

とすれば万事解決します。
これでも心配ならswitch 文の条件に

case 1:case "1":

という風に両方書いておけば完璧です。
 
2.Boolean型以外をif分の条件に使用しない
僕も今までかなり手抜きしてますが、

if (flag!=0) {}

このように、明示的にどういうときにtrueでどういうときにfalseなのかを仕様を信用せずに書いた方が良さそうです

以上、今回はこれで対応できたので、同じようなことに困ったら参考にしてもらえればと思います。

HTML5飯