JavaScriptで呼び出し元の関数名を取得する方法 考えてみた

まず最初に断わっておきます。

JavaScript に "正式サポート" されてるメソッドはありません。

でもどうにかして 関数呼び出し元 を調べたい場面がありました、

その記録を残しておくために、
ここでは JavaScriptで呼び出し元関数名の取得方法 をまとめてみます。

方法1.Function.caller を使う(非推奨&strictではNG)

まず試したのは Function.caller  から取得するやり方

文字通り 関数オブジェクト の呼び出し元(caller)のことです。

▼ MDNでの Function.caller  の説明

この機能は標準ではなく、標準化の予定もありません。公開されているウェブサイトには使用しないでください。ユーザーによっては使用できないことがあります。実装ごとに大きな差があることもあり、将来は振る舞いが変わるかもしれません。

function.caller プロパティは、指定した関数の呼び出し元の関数を返します。このプロパティは再帰最適化のため、strict モードでは使用できません。

引用元 : Function.caller - JavaScript | MDN

この説明の通り、 strictモード では一切機能しないので要注意!

あと非推奨なので、テスト以外には使わない方がいいかも。

少なくとも公開してるサイト・サービスでは使わないのが安全ですね。

 

例えばこういうコードで呼び出し元が取得可能

▼ 呼び出し元関数名を取得するコード例

▼このコードの出力結果

最新Chromeと FireFox で試したら取得はできました。一応は・・・

 

だけど、 'user stricts';  を使うとエラーになります。

▼ このコードの出力結果(エラー)

こういうリスクもあるので、呼び出し元取得には使いにくいです。

方法2.意図的に例外発生させて関数名取得する

2つめは例外を利用して取得する方法

現時点では最も良さげかもしれないやり方です。

 

例えば関数内で例外発生すると、次みたいなスタックメッセージが返ってきます。

例外を意図的に発生させれば、呼び出し元を強引だけどゲットすること ができます。

 

たとえば実際に書いてみたのが次のコードです。

▼ 呼び出し元関数名を取得するコード例

▼ このコードの出力結果

一応取得はできてるけど・・・

やっぱり例外処理を利用するのはどうかなという感じ。

公式で呼び出し元を取得するメソッドが実装されてほしいですね。

方法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で呼び出し元の関数名取得する方法(?)でした。ではまた

Shareこの記事をシェアしよう!

Commentsこの記事についたコメント

4件のコメント
  • さとう

    console.trace() でも見れると思います!

    9月 12, 2020 5:48 am
  • さとう

    console.trace() の結果は、 Javascript から触れなそうですね・・・失礼しました。

    9月 12, 2020 5:50 am
    • ぴー助

      コメントありがとうございます!そういう機能もあるとは知りませんでした。ただ利用場面は制限され、MDNリファレンスによると「この機能は Web Workers 内で利用可能」のようです。とはいえそういった場面では役立つかもしれません。

      9月 12, 2020 12:19 pm
  • さとう

    new Error().stack
    が限界そうでした・・・( これだと catchブロックには入りませんでした)

    9月 12, 2020 5:58 am

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください