scriptNote_09

dA-tools.com

HOME > AfterFx > Script Labs > Script_note > scriptNote_09

スクリプト・雑記

Scope

Feb/2 2009

CS3まで使えていたスクリプトがCS4でエラーになったのがキッカケで変数のスコープについて改めて調べてみた。今までもどうしてこんな値を返してくるのかわからないことがあったのだが納得した。なんとなく他の言語と同じように思っていてはだめですね。

グローバルとローカル

  • 変数のスコープを確認するために次のスクリプトを書いて実行してみました。(@CS4)

scope1

  • 17行
    • yは当然S1
  • 18行では関数Fx_A()を呼び出し
    • 4行でvar命令でyを宣言して"Local Fx_A"を代入
    • 5行でvarを省略してyyに"no var yy"を代入
    • 13行で関数Fx_B()を呼び出し
      • 8行でvar命令でyを宣言して"Local Fx_B"を代入
      • 9行でvarを省略してzzに"no var zz"を代入
      • 10行でyを返します。
      • ここでyの値は?
      • 8行目で代入した"Local Fx_B"です。全然問題なし。
    • 14行目でもyを返します。このyの値は?
      • Local Fx_B じゃなくて Local Fx_A です。
      • 関数の中で宣言した変数はローカル変数だから。
  • 19行のyyの値は?
  • ここでC++ やJavaのプログラミング経験があるとエラーになると思うでしょう。ブロックの中の変数はその中だけで有効、いわゆるブロックスコープだよ、って。ところがJavaScriptにはブロックスコープがないのです。ブロックを抜けても変数が有効です。
  • というわけで19行ではno var yy、20行では no var zzが表示されます。
  • でも、関数の中で宣言した変数はローカル変数って言ったじゃないか!
  • JavaScriptでは変数の宣言を省略できるのでyyとzzはvarを使わずにいきなり値を代入しています。しかしvar宣言を省略すると変数はグローバル変数として扱われるのです。だから関数の外からでも呼び出しが出来ます。コードの背景が白い部分は全てグローバルのスコープにあるってことです。
  • 21行のyの値は?
  • Local Fx_A ? ではなくてグローバルのyS1です。
  • 最後の23行は? ローカル関数を呼んでいるのでエラーです。

ポイント

  1. 変数の中でvar命令で宣言した変数はローカル変数。
  2. var命令を省略するとグローバル変数になる。
  3. JavaScriptにはブロックスコープがない。

宣言も代入もしていないのに…

  • scope02.jpgさて、先ほどのスクリプトを終了して右のスクリプトを実行するとどうなるのか?
  • 変数を1つも宣言してないからもちろん全部エラー。
  • とはならず、上のスクリプトとまったく同じ結果になります。えっ?!
  • (adobe)Extend Scriptではグローバル環境は共有されるのです。ですからソフトを起動して一度宣言したグローバルな変数や関数は保持されているのでこんなことになります。
  • GlobalVar.jpgESTKのデータブラウザを見てもその様子が判ります。
  • このグローバル環境はソフトを終了するまで維持されます。ガベージコレクションの対象にはならないようです。

結論

  • ローカル変数の定義には必ずvar命令を使いましょう。
  • グローバル変数でもvar命令を使いましょう。
  • 変数は必ず初期化しましょう。変数名の競合があっても上書きしてしまえば問題ないですから。
  • 受け渡しが楽だけれどもグローバル変数の乱発は避けましょう。
  • 結局、至極当たり前な結論(^^;)
Scripters should be careful about giving variables in scripts unique names, so that a script does not inadvertently reassign global variables intended to persist throughout a session.
  • (JavaScript tools Guide より)

Startup script

  • 頻繁に使う関数はStartup scriptに書いておけば #include しなくても使えるってことですね。