質問: コードをgrepする方法を除きブラウザのjsコンソールなどからあるオブジェクトがどこから由来したか調べる方法はありますか? 具体的には、あるwebサイトのjsコンソールに'hoge'というオブジェクトがいて、これがどのファイルで(またどのファイルでもない)定義されているかコンソール上から追うにはどうしたら良いでしょうか. またjsのオブジェクト空間(という名称は一般的ですか?)のログ見る方法はありますか. つまりどの瞬間にどのオブジェクトがどの様な順番で定義されているか見てみたいです.
回答: コンソールから直接そのようなことを調べることは、私の知る範囲ではできません。できないのです。できませんが、問題解決のためにオブジェクトのツリー情報を調べる方法はいくつかあります。 オブジェクト、DOM 要素を調べる 調べたいオブジェクトが target であるとします。 ``` console.dir(target) // オブジェクトの情報と可能であればその位置を出力 function list( obj) { for(var o in (obj == null ? [] : obj)) if(obj.hasOwnProperty(o)) console.log( typeof o + ": " + o); } list(target) // オブジェクトのプロパティのみを列挙 ``` Grep のように、オブジェクトを名前からツリー検索する Waldo というライブラリが軽量で便利です。まず以下のコードをコンソールに流します: ``` javascript:(function(d){function a(f,i,g,h){(!i||typeof g==i)?e(f,g,h):console.error(g+" must be "+i)}function e(n,h,s){n=b[n]||n;s||(s={});var m;var j;var l=s.obj||d;var q=s.hasOwnProperty;var r=s.path||((l==d)?"global":"");var o=[{obj:l,path:r}];var f=[];while((m=o.pop())){l=m.obj;r=m.path;for(var g in l){try{if(q.call(l,g)){if([l[g]]=="[object Object]"){for(var k=-1;f[++k]&&!(j=c(f[k].obj,l[g])&&f[k]);){}if(!j){m={obj:l[g],path:r+"."+g};o.push(m);f.push(m)}}if(n(h,l,g)){console.log(r+"."+g,"->","("+(j?"<"+j.path+">":typeof l[g])+")",l[g])}}}catch(p){}}}}function c(f,h){if(f===h){return true}if(!(f instanceof Object)||!(h instanceof Object)){return false}if(f.constructor!==h.constructor){return false}for(var g in f){if(!f.hasOwnProperty(g)){continue}if(!h.hasOwnProperty(g)){return false}if(f[g]===h[g]){continue}if(typeof(f[g])!=="object"){return false}if(!c(f[g],h[g])){return false}}for(g in h){if(h.hasOwnProperty(g)&&!f.hasOwnProperty(g)){return false}}}var b={propName:function(f,g,h){return f==h},type:function(f,g,h){return g[h] instanceof f},value:function(f,g,h){return g[h]===f},valueCoerced:function(f,g,h){return g[h]==f}};d.find={byName:function(f,g){a("propName","string",f,g)},byType:function(f,g){a("type","function",f,g)},byValue:function(f,g){a("value",null,f,g)},byValueCoerced:function(f,g){a("valueCoerced",null,f,g)},custom:function(g,f){e(g,null,f)}}}(this)); ``` そうすると、以下のようにして、名前でオブジェクトを検索することができるようになります。 ``` find.byName("window"); find.byName("open"); find.byName("click"); ``` オブジェクト、 DOM 要素を調べる (Chrome のみ) 調べたいオブジェクトが target であるとします。 ``` dir( target) // 中身の列挙 table( target) // 中身の列挙 (テーブル形式で出力) inspect( target) // 中身の列挙 (DOM 要素だと要素パネルで表示) ``` これらのAPIは、他のブラウザでも FireBug を導入すれば使用可能になります。 その瞬間の実行環境の状態を見る ( Chrome のみ) まず、コンソールプロンプトで: ``` debugger ``` と打っておき、気が向いたときに、 Enter キーを押します。 この操作では、高い動体視力が必要になることがあります。できない場合は、ソースコードに: ``` debugger; ``` と直接、埋め込んでおいてもよいです。後は、コンソール外部での操作になるので、この質問のスコープ外となります。インスペクタなり、プロファイラでも使って適当に調べてください。その状態から `console.dir( target)` とするのもよいでしょう。