例えば、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(){ ... }
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 を参照することが出来るのは知ってたんですが・・・。var v = 1;
return function (){return 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(){ ... }
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年も前だからなぁ。すでにどっかでやってたりして・・・。ちょろっとググッただけです。もし同じようなものあったらごめんなさい



この記事へのコメント