JavaScript:在其内部获取函数名

JavaScript:在其内部获取函数名,javascript,jquery,extjs,arguments,Javascript,Jquery,Extjs,Arguments,是的,首先,我意识到关于这个问题有无数的线索: 但给出的答案的问题是。所有的答案都是给你的函数起个名字。然而,据我所知,这并不能解决我的问题。假设我有以下功能: function blah() { // arguments.callee.name is deprecated console.log('The function name is: ' + arguments.callee.name + '.'); } 但是因为它已经被弃用了,所以我不应该使用它,那么我应该使用什么来代

是的,首先,我意识到关于这个问题有无数的线索:

但给出的答案的问题是。所有的答案都是给你的函数起个名字。然而,据我所知,这并不能解决我的问题。假设我有以下功能:

function blah() {
  // arguments.callee.name is deprecated
  console.log('The function name is: ' + arguments.callee.name + '.');
}
但是因为它已经被弃用了,所以我不应该使用它,那么我应该使用什么来代替呢?当我在函数本身内部时,是否有任何方法可以访问函数名,或者我只是不太可能在这里访问


如果它让事情变得更简单,我使用的是框架ExtJS,但我还没有找到知道函数名称的方法。如果没有,是否有jQuery方法?我在这里绝望了。

您可以引发异常并检查堆栈跟踪

以下上下文证明在Chrome浏览器中有效:

function test () {
  try { [].undef () } catch (e) {
     console.log (e.stack.split ('\n')[1].split (/\s+/)[2]);
  }
}
要获得更健壮的实现,请咨询 它在任何浏览器中都提供完整的堆栈跟踪


我想出了一个更现代、更全面的堆栈跟踪分析器,它有一些改动,因此在此基础上,我提出了一个非常实用的解决方案(在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(删去很多行)

Chrome(前两行是我必须容纳的垃圾……之后,它类似于FF的堆栈字符串)

“错误
在错误时(对于一个工作示例),我们必须更改堆栈值,因为我们不再使用ExtJS


现在,有一点解释。
getLogLocation
作为一个函数驻留在Ext JS类(
ConsoleMixin
)中,ConsoleMixin(
logMessage
)内部的另一个函数调用getLogLocation,而logMessage则由外部类的函数(
constructor
)调用,这就是我必须补偿前两个堆栈值的原因。正如我所说,非常粗糙,并且针对我的需要,但希望有人能利用它。

有没有一种情况是你不能硬编码函数名?我同意能够通过编程获得它会很好,但这是必要的?嗯,是的。我正在尝试创建某种类型的日志记录机制,我不想用设置的名称调用日志机制…我只想让它知道名称。这样做更有意义,因为它是动态的。如果函数名更改,我可能会忘记为记录器更改它。查看现代b中可用的一些堆栈跟踪可见性机制可能更容易Rowser。它们不相互兼容,但可能会更干净,因为你不必显式地传递任何东西。是的,我在发布这个问题之前看到了整个堆栈跟踪方法,但似乎有点过分。我不明白为什么这么简单的事情基本上是不可能的。有趣的是,我确实看到了堆栈跟踪libra嗯……这可能是我目前唯一的选择。让我困惑的是,这太难了。这是你的Javascript!:-)可怜的JavaScript…它只是试图从一个孩子成长为一个成年人,但不幸的是它还停留在焦虑的青少年阶段。@HBP,谢谢你的想法,顺便说一句…这就是我的答案。这绝对是我迄今为止看到的最有趣的方法。
".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
..."
"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)
    ..."