2007年02月10日

Javascipt:関数が終了した後でもそのローカル変数が参照できる

2/15 追記:関数化はこちら「Javascipt:関数の状態をトレースする関数」

例えば、fn(){var v=1;}を起動・終了後に v が参照出来るんですが、さらにそれを汎用にしてしまったものです。元ネタは以下リンクですが、caller(呼出し元)も一応は記録しておくことが出来るんじゃないかと。

JavaScriptでDebugScreen、その2(最速インターフェース研究会さん)

1年前の古い記事です。つい今しがた見つけてw衝撃を受けましたんで色々イジってみる。いつも参考にさせてもらってます。m(_ _)m



 ソースの簡易化

まず、元のソースは汎用性のため、ちょっと複雑なので展開してみます。
//呼出される関数
function clee(){
  // ここで環境を保存
  window.__args__ = arguments;
  window.recall = function(n){
    return n == 'arguments' ? window.__args__ : eval(n);
  }
  // 以下関数固有の処理
  var v = "keep!";
};

// 呼出し元の関数
function cler(){clee(1, 2, 3);}

// 呼出し元の関数を起動して、呼出される関数を起動する。
cler();
// 保存されているか確認
alert(recall("v")); // keep !
alert(recall("arguments")[0]); // 1
alert(recall("arguments").callee); // function clee(){ ... }
alert(recall("caller")); // function cler(){ ... }

びっくりしたのは5行目の eval(n)。例えば、
function fn(){
  var v = 1;
  return function (){return v;}
}
であれば、返された関数で v を参照することが出来るのは知ってたんですが・・・。
eval(n) でその変数名を与えるとその名前の変数を参照できる。こりゃすごい。

 改造

んで。ちょっと改造w ローカル変数が参照できるなら以下2点。
  • window.__args__ ではなくてもいい(ローカルでも良くない?)
  • どうせなら caller も保存してしまうw
//呼出される関数
function clee(){
  // ここで環境を保存
  window.recall = function(n){return eval(n);}
  var caller = arguments.callee.caller;
  var args = arguments;
  // 以下関数固有の処理
  var v = "keep!";
};

// 呼出し元の関数
function cler(){clee(1, 2, 3);}

// 呼出し元の関数を起動して、呼出される関数を起動する。
cler();
// 保存されているか確認
alert(recall("v")); // keep !
alert(recall("args")[0]); // 1
alert(recall("args").callee); // function clee(){ ... }
alert(recall("caller")); // function cler(){ ... }

んで、「ここで環境を保存」の部分を文字列として、eval に与えられる様にしてやれば、使い回しもok。firefox も。現状、変数名が分からないと参照できないのが、ちょっと残念なところです。んが、面白い。

1年も前だからなぁ。すでにどっかでやってたりして・・・。ちょろっとググッただけです。もし同じようなものあったらごめんなさいふらふら
posted by HiFa at 11:19 | 🌁 | Comment(0) | TrackBack(0) | JavaScript雑感 | このブログの読者になる | 更新情報をチェックする
>>> スパムコメントは消してますよん。 お互い無駄な労力は避けましょう。 <<<

この記事へのコメント

コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/33338956
※言及リンクのないトラックバックは受信されません。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。