JavaScript:获取自身内部的函数名称

时间:2013-10-21 18:52:43

标签: javascript jquery extjs arguments

是的,我知道有很多关于这个问题的线索,对于初学者来说:

Get function name from function itself [duplicate]

Get function name from inside itself

Arguments.callee is deprecated - what should be used instead?

但答案的问题是arguments.callee is deprecated。所有答案都说只是给你的功能一个名字。但是,据我所知,这并不能解决我的问题。说我有以下功能:

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

但是因为它被弃用了,我不应该使用它,所以我应该使用什么呢?有什么办法可以在函数本身内部访问函数名,或者我的概率是不是在这里?

如果它让事情变得更容易,我使用的是Ext JS框架,但我还没有找到一种了解函数名称的方法。如果没有,是否有jQuery方法?我在这里绝望。

2 个答案:

答案 0 :(得分:3)

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

以下上下文证明适用于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

答案 1 :(得分:0)

随着一些探索,我提出this SO thread,所以建立在其上,我做了一个非常非常hacky解决方案有效(在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的堆栈字符串)

"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)
    ..."

有关工作示例,请参阅this jsFiddle ...必须更改堆栈值,因为我们不再使用Ext JS。

现在,一点解释。 getLogLocation作为Ext JS类(ConsoleMixin)中的函数驻留,而ConsoleMixin(logMessage)内的另一个函数调用getLogLocation,logMessage由外部类的函数调用({{ 1}}),这就是我必须补偿前2个堆栈值的原因。就像我说的那样,非常hacky和具体到我的需要,但希望有人可以利用它。