JavaScript変数のスコープについて

January 23, 2011
After Effects スクリプティングメモ」更新しました。同様の記事をblogの方にもエントリーしておきます。なんでこんなことではまっちゃうのか、自分でも嫌になりますが。でも案外、人から頂いたスクリプトもグローバル変数関連がちゃんと処理されてなかったりするので、結構これではまる人多いんじゃないかなと思ってます。「AE再起動すると治った(あるいは動かなくなった)」ってのは大抵これの問題。

ブログにまで書いて恥さらす必要があるのかはわかりませんが...

恥ずかしながら自分がかなりハマってしまった問題です。これはAfterEffectsに特化した問題ではなくJavaScript全般の問題です。
JavaScriptの変数スコープはちょっと特殊です。まず下のコード

for(var i=0; i<100; i++) {
   var myValue = 'this value';
}
alert(typeof myValue); 

私はJavaScriptではブロックで変数のスコープが発生「しない」という仕様を知らなかったので、この場合alertがundefinedを返してくることを期待してました...が、実際には本人の意図とは裏腹にグローバル変数を定義してしまっていたということになります。更にJavaScriptの困った仕様として以下のようなものもあります。...


function tryThisFunction(){
   for(i=0; i<100; i++) {
      var myValue = 'this value';
   }
}

var myGlobal = tryThisFunction();
alert(i);

この例ではfor文の中で宣言なしでi=0という変数を定義しているために、iがグローバル変数になってしまってます。JavaScriptでは未宣言の変数を使用したときに自動的に「グローバルスコープ」で宣言されちゃいます。このバグが比較的複雑なコードの中に紛れると結構厄介な上に、発見したときの精神的な破壊力が半端ないです。もうこの仕様は欠陥といって差し支えないと思うんですけど...

これも『JavaScript: The Good Parts』(関連記事)に詳しく書かれてました。もっと早くに読んでおけばよかった...