5

はい、私はこの問題について無数のスレッドがあることを認識しています。

関数自体から関数名を取得する[複製]

自身の内部から関数名を取得

Arguments.callee は非推奨です - 代わりに何を使用する必要がありますか?

しかし、与えられた答えの問題は、arguments.callee is deprecated です。すべての答えは、関数に名前を付けるだけだと言っています。ただし、私が知る限り、それで問題は解決しません。次の機能があるとします。

function blah() {
  // arguments.callee.name is deprecated
  console.log('The function name is: ' + arguments.callee.name + '.');
}

しかし、それは推奨されていないため、使用すべきではありません。代わりに何を使用する必要がありますか? 関数自体の内部で関数名にアクセスできる方法はありますか、それともここで確率が低いだけですか?

作業が簡単になる場合は、フレームワーク Ext JS を使用していますが、関数の名前を知る方法が見つかりません。そうでない場合、jQuery のアプローチはありますか? 私はここで必死です。

4

2 に答える 2

2

例外を発生させ、スタック トレースを調べることができます。

次のコンテキスト証明は、Chrome ブラウザーで機能します。

function test () {
  try { [].undef () } catch (e) {
     console.log (e.stack.split ('\n')[1].split (/\s+/)[2]);
  }
}

より堅牢な実装については、 http: //www.eriwen.com/javascript/js-stack-trace/ を参照してください 。どのブラウザーでも完全なスタック トレースが提供されます。

より最新で包括的なスタック トレース アナライザーは、http://stacktracejs.comです。

于 2013-10-21T19:19:28.410 に答える
0

いくつか突っ込んで、私はこのSOスレッドを思いついたので、その上に構築して、機能する非常にハックなソリューションを作成しました(ChromeとFFの両方で... IEについてはわかりませんが、機能するとは思えません)。 警告:これは私自身の使用に非常に固有のものであるため、走行距離は確実に異なります. とにかく、これは私のコードです:

getLogLocation: function() {
  var ua = navigator.userAgent;
  var isFF = ua.search(/firefox/i) !== -1 ? true : false;
  var isChrome = ua.search(/chrome/i) !== -1 ? true : false;
  if (isFF || isChrome) {
    var stack = Error().stack,
        cname = '',
        funcPattern,
        classPattern = /.*\/(.*)\.js/;  // looking for something between the last backslash and .js
    if (stack) {
      var stacks = stack.split('\n');
      if (stacks) {
        var theStack;
        // the browsers create the stack string differently
        if (isChrome) {
          // the stack has getClassName, then logMessage, then our calling class, but Chrome has some added garbage
          theStack = stacks[4];
          funcPattern = /.*\.(.*)\s+\(/;   // looking for something between a period and the first paren
        }
        else {
          theStack = stacks[2];
          funcPattern = /^\.*(.*)\@/;  // looking for something between a period and an @ symbol
        }
        var matches = theStack.match(classPattern);
        cname = matches[1] + '::';
        matches = theStack.match(funcPattern);
        cname += matches[1] + ':';
      }
    }
    return cname;
  }
}

私のスタックがどのように見えるか知りたい場合は、関連する行を次に示します。

Firefox (多くの行を切り取る)

".getClassName@http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836090216:72
.logMessage@http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836090216:31
.constructor@http://127.0.0.1/javascripts/app/BaseController.js?_dc=1383836089659:39
..."

Chrome (最初の 2 行は、私が対応しなければならないゴミです...その後は、FF の Stack 文字列に似ています)

"Error
    at Error (<anonymous>)
    at Ext.define.getLogLocation (http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836606405:72:19)
    at Ext.define.logMessage (http://127.0.0.1/javascripts/app/mixins/ConsoleMixin.js?_dc=1383836606405:31:24)
    at new Ext.define.constructor (http://127.0.0.1/javascripts/app/BaseController.js?_dc=1383836606265:39:14)
    ..."

動作する例については、この jsFiddleを参照してください... Ext JS ではなくなったため、スタック値を変更する必要がありました。

では、少し説明を。 getLogLocationは Ext JS クラスの関数として存在し ( ConsoleMixin)、ConsoleMixin 内の別の関数 ( logMessage) は getLogLocation を呼び出し、logMessage は外部クラスの関数 ( constructor) によって呼び出されます。これが、最初の 2 つのスタック値を補正する必要がある理由です。私が言ったように、非常にハックで私のニーズに固有のものですが、誰かがそれを利用できることを願っています.

于 2013-11-07T15:07:56.403 に答える