【问题标题】:javascript - arguments.callee.toString() and arguments.callee.name does not return function namejavascript - arguments.callee.toString() 和 arguments.callee.name 不返回函数名
【发布时间】:2009-12-20 11:03:38
【问题描述】:

我正在尝试获取当前正在运行的函数的名称。根据我的阅读,这应该可以使用:

(arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/)

但是,当我在 Firefox 和 Safari(Mac 上的最新版本)中运行它时,不会返回名称。

console.log( arguments.callee ) 返回函数的源,但不返回分配的名称。 arguments.callee.name 返回一个空字符串。

我的示例代码如下:

var testobj = {
    testfunc: function(){
        console.log( (arguments.callee.toString()).match(/function\s+(\[^\s\(]+)/) );
    }
}
testobj.testfunc();

【问题讨论】:

标签: javascript function


【解决方案1】:

你声明了一个匿名函数

function(){

你应该把它声明为

function testfunc(){

打印名字。

【讨论】:

  • 请注意,命名函数表达式(这是您所建议的)在 IE 中的行为很奇怪。见yura.thinkweb2.com/named-function-expressions
  • 澄清:在上面的对象样式的情况下,这将是{ testfunc: function testfunc() { ...。在浏览器中调试时这样做也很好,可以帮助调试器帮助您查看您在哪个功能中遇到问题。
  • 根据Wayback Machine,@TimDown 评论中的链接在域名过期前重定向到kangax.github.com/nfe
【解决方案2】:

典型的 arguments.callee hack 在这里不起作用,因为您所做的事情被分配了一个匿名函数作为对象的 'testfunc' 键的值。在这种情况下,黑客攻击会变得更糟,但可以这样做,如下所示:

var testobj = {
    testfunc: function(){
      for (var attr in testobj) {
              if (testobj[attr] == arguments.callee.toString()) {
                  alert(attr);
                  break;
                }
            }
    }
}
testobj.testfunc();

【讨论】:

    【解决方案3】:

    在 Firefox 3.5、Safari 5 和 Chrome 6.0 上,您可以使用:

    function myFunctionName() {
     alert("Name is " + arguments.callee.name );
    }
    
    myFunctionName();
    

    您还可以使用 arguments.callee.caller 获取调用当前函数的函数。

    【讨论】:

      【解决方案4】:
      /function\s+(\[^\s\(]+)/
      

      [ 之前的反斜杠是什么意思?我不认为你想要一个文字方括号。没有它应该可以工作。

      虽然我强烈建议不要与嗅探函数名称或特别是嗅探调用函数有关的任何事情。使用这些可怕的技巧几乎可以做的任何事情都最好使用闭包和查找的组合来完成。

      【讨论】:

        【解决方案5】:

        我认为有一个更简洁优雅的解决方案可以解决所有这些问题。假设函数是某个更高级别对象的成员——情况总是如此,即使函数的所有者是“窗口”或其他全局对象,我们也可以通过 this 关键字,我们可以通过 arguments.callee 访问函数本身,我们可以通过 for (var o in this) 访问所有父对象(函数)名称,所以你应该能够相当容易地获得所需的信息......

        returnMyName = function() {
          for (var o in this) {
            if (arguments.callee===this[o]) return o;
          }
        };
        

        这应该是健壮的,并避免任何奇怪的 IE 浏览器行为访问命名函数等。

        【讨论】:

          【解决方案6】:
          Function.prototype.getName = function(fn) {
              if(Function.name || Function.prototype.name) return this.name;
              return this.toString().match(/^function\s+(\w+)\s*\(/)[1];
          };
          

          【讨论】:

          • 请添加答案描述!
          【解决方案7】:

          首先,函数没有名字。函数名称是您在function 和参数列表(...) 之间放置的名称。以下是获取函数名称的方法(不要使用name 属性,因为它可以更改):

          var fName = arguments.callee.toString(0).match(
            /^function\s*(?:\s+([\w\$]*))?\s*\(/
          );
          fName = (fName ? fName[1] : "");
          

          【讨论】:

          • “不要使用 name 属性,因为它可以更改” - 好吧,toString() 方法也可以更改...
          【解决方案8】:

          我发现如果你只是简单地记录函数对象,像这样:

          console.log(arguments.callee)
          

          console.debug(arguments.callee)
          

          您只需通过一些选项在控制台日志中获取函数名称。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2011-11-05
            • 1970-01-01
            • 2012-03-12
            • 1970-01-01
            • 2012-07-30
            相关资源
            最近更新 更多