まず最初に断わっておきます。
JavaScript に "正式サポート" されてるメソッドはありません。
でもどうにかして 関数呼び出し元 を調べたい場面がありました、
その記録を残しておくために、
ここでは JavaScriptで呼び出し元関数名の取得方法 をまとめてみます。
このページの目次
方法1.Function.caller を使う(非推奨&strictではNG)
まず試したのは Function.caller から取得するやり方
文字通り 関数オブジェクト の呼び出し元(caller)のことです。
▼ MDNでの Function.caller の説明
この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。
function.caller プロパティは、指定した関数の呼び出し元の関数を返します。このプロパティは再帰最適化のため、strict モードでは使用できません。
この説明の通り、 strictモード では一切機能しないので要注意!
あと非推奨なので、テスト以外には使わない方がいいかも。
少なくとも公開してるサイト・サービスでは使わないのが安全ですね。
例えばこういうコードで呼び出し元が取得可能
▼ 呼び出し元関数名を取得するコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function hoge(){ if(hoge.caller == null){ console.log('caller : NONE'); }else{ console.log('caller : ', hoge.caller.name); } } function fuga(){ hoge(); } fuga(); hoge(); |
▼このコードの出力結果
1 2 |
caller : fuga caller : NONE |
最新Chromeと FireFox で試したら取得はできました。一応は・・・
だけど、 'user stricts'; を使うとエラーになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
/// strictモードを有効化 'use strict'; function hoge(){ if(hoge.caller == null){ console.log('caller : NONE'); }else{ console.log('caller : ', hoge.caller.name); } } function fuga(){ hoge(); } fuga(); hoge(); |
▼ このコードの出力結果(エラー)
1 |
Uncaught TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them |
こういうリスクもあるので、呼び出し元取得には使いにくいです。
方法2.意図的に例外発生させて関数名取得する
2つめは例外を利用して取得する方法
現時点では最も良さげかもしれないやり方です。
例えば関数内で例外発生すると、次みたいなスタックメッセージが返ってきます。
1 2 3 4 5 |
Error at hoge (example.html:10) at fuga (example.html:21) at piyo (example.html:25) at example.html:28 |
例外を意図的に発生させれば、呼び出し元を強引だけどゲットすること ができます。
たとえば実際に書いてみたのが次のコードです。
▼ 呼び出し元関数名を取得するコード例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
'use strict'; function hoge(){ var callerName = null; try { throw new Error(); } catch (e) { var callerName = 'NONE'; var re = /(\w+)@|at (\w+) \(/g, st = e.stack, m; while(m = re.exec(st)){ callerName = (m != null) ? m[1] || m[2] : 'NONE'; } } console.log('caller : ', callerName); } function fuga(){ hoge(); } fuga(); hoge(); |
▼ このコードの出力結果
1 2 |
caller : fuga caller : NONE |
一応取得はできてるけど・・・
やっぱり例外処理を利用するのはどうかなという感じ。
公式で呼び出し元を取得するメソッドが実装されてほしいですね。
方法3.console.traceでも限定的に取得可能
2020年09月12日追記
記事へのコメントで教えていただきました。
どうやら console.trace でも取得可能みたいです。
▼ MDNでの解説
console インタフェースの trace() メソッドは、Web コンソールにスタックトレースを出力します。この機能は Web Workers 内で利用可能です。詳細や使用例については、console のドキュメントの スタックトレース をご覧ください。
引用元 : https://developer.mozilla.org/ja/docs/Web/API/console/trace
でもこの説明にもある通り・・・
「Web Workers 内で利用可能」
こういう制限があるみたいですね。
とはいえ Web Workers を使う場面(メインスレッドとは別で並列処理とか)では役立ちそうです。ただ自分自身、Web Workers は良く分かってないですが・・・
コメントありがとうございました。
ここまでのまとめ
ここまでの取得方法のまとめ
- Function.caller を使う
ある関数の呼び出し元の関数を返すプロパティ。関数名は func.caller.name のように取得できるが、標準化されてなく stringモードでは利用不可
- 意図的に例外発生させて関数名取得
例外発生時のメッセージに関数名が表示されるので、それを利用するやり方。取得はできるけど、正しい例外の使い方ではない
もし「いい方法知ってるよ!」という方はコメントで教えていただきたいです。
以上、JavaScriptで呼び出し元の関数名取得する方法(?)でした。ではまた