ウェブサイト検索

javascript - TypeScript のメソッド内でメソッド名を取得する


TypeScriptでクラスのインスタンスメソッド内から現在のメソッドの名前を取得したいです。

(擬似コード、動作しません):

class Foo {
    bar() {
        console.log(something); //what should something be?
    }
}

new Foo().bar();

私は 'something' が 'bar' を返すことを期待しています。this がクラスを取得できることは分かっていますし、そこからクラスとその属性を取得する方法もあるかもしれませんが、'この関数'(つまり、クラス Foo ではなくメソッド bar)をどうやって取得するかは分かりません。

クラス名などを見つけることに関連する他のいくつかの質問は見たことがありますが、現在のメソッド名を取得することに関するものはありませんでした。

回答 #1

arguments.callee.name以外に、これを取得する直接的な方法はありません。

私は他に2つの方法を提案します。

デコレーターを使ってメソッド名を注入する:

function annotateName(target, name, desc) {
    var method = desc.value;
    desc.value = function () {
        var prevMethod = this.currentMethod;
        this.currentMethod = name;
        method.apply(this, arguments);
        this.currentMethod = prevMethod;   
    }
}

class Foo {
    currentMethod: string;

    @annotateName
    bar() {
        alert(this.currentMethod);
        this.tux();
        alert(this.currentMethod);
    }

    @annotateName
    tux() {
        alert(this.currentMethod);
    }
}

new Foo().bar();

欠点は、名前を取得したいすべての関数に注釈を付ける必要があることです。代わりにクラスにだけ注釈を付け、デコレーターの中ですべてのプロトタイプ関数を反復処理して同じアイデアを適用することもできます。

私の二番目の選択肢は標準化されておらず、ブラウザ間で一貫した結果を得るにはより注意が必要です。これは、Errorオブジェクトを作成し、そのスタックトレースを取得することに依存しています。

class Foo {
    bar() {
        console.log(getMethodName());    
    }
}

function getMethodName() {
    var err = new Error();
    return /at \w+\.(\w+)/.exec(err.stack.split('\n')[2])[1] // we want the 2nd method in the call stack

}

new Foo().bar();

回答 #2

こちらがメソッド名を取得するための私の解決策です。

  /**
   * @description Get log invoker name
   * @return {string} The invoker name
   */
  private static callerName(): string {
    try {
      throw new Error();
    } catch (e) {
      try {
        return e.stack.split('at ')[3].split(' ')[0];
      } catch (e) {
        return '';
      }
    }
  }

関連記事