練炭ブログ

萌え壁紙、Irvine、DMonkey、Proxomitron などの情報を扱ってます。

DMonkey: 名前付き関数式からの参照

コメントなし»

過去に書いた名前付き関数式で定義されたグローバル関数からはクロージャが使えないからの関連で。

参照先オブジェクトが属するスコープから抜ける前なら(クロージャとしての定義時の環境ではなく実行時の環境として)、名前付き関数式のブロック内から参照することは出来ます。

(function () {
  (function () {
    function common_load () {
      void function x () { alert (typeof common_load); };
    };
    common_load ();

    x ();  // function (まだ生きている)
  }) ();

  x ();  // undefined (スコープを抜けたので消失)
}) ();

Dorothy2 の Dorothy2A.dms では OnHttpRequest() 内で common_load() が定義されていて、実行終了まで OnHttpRequest() を抜けないので、common_load() で実行したスクリプトで名前付き関数式によって定義された関数内からも common_load() を呼び出せる、という挙動のようです。

あと名前付き関数式でなくて無名の関数式(を変数に代入したもの)でもスコープ抜けたら参照できなくなります。

Irvine/Dorothy2: common で複数の関数を定義する

コメントなし»

ほとんど自分用メモ。

common_load() で読み込まれる .dms ファイル(Dorothy2\common\*.dms)で、一つのファイル内で複数の関数を定義したい場合、

function a () {
...
}

function b () {
...
}

のように普通に関数を並べるとエラーになってしまう。

common_load() は .dms ファイルをテキストとして読み込んで eval() するという実装なのだけど、eval() で評価できるのは式であって文ではないので、これがエラーになる(用語は適当)。

以下のようにすれば複数の関数を定義できる。

パターン1
カンマで繋げる

function a () {
...
}, // ←

function b () {
...
}

パターン2
一つのオブジェクトに入れる

X = {
a: function () {
...
},

b: function () {
...
}
} // end X

呼び出す時は X.a () のようにする。

ただし var x = { ... } とするとエラーになる。var は式で使えず、書くと文になってしまうので。

他にもやり方はあるんじゃないかと思う。