javascript - arguments.callee.toString()和arguments.callee.name不返回函数名称

时间:2009-12-20 11:03:38

标签: javascript function

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

(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();

8 个答案:

答案 0 :(得分:10)

您使用

声明了匿名函数
function(){

您应该将其声明为

function testfunc(){

打印名称。

答案 1 :(得分:8)

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

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

答案 2 :(得分:3)

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

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

myFunctionName();

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

答案 3 :(得分:2)

/function\s+(\[^\s\(]+)/

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

虽然我强烈建议不要与嗅探函数名称或特别是嗅探调用函数有关。使用这些可怕的黑客攻击几乎可以使用闭包和查找的一些组合来完成。

答案 4 :(得分:2)

我认为这一切都有一个更清洁,更优雅的解决方案。假设函数是某个更高级别对象的成员 - 并且总是如此,即使函数的所有者是“窗口”或其他一些全局对象,我们也可以通过 this <来访问全局对象/ b>关键字,我们可以通过 arguments.callee 访问函数本身,我们可以通过 for(var o in this)访问所有父对象(函数)名称,所以你应该可以很容易地得到所需的信息......

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

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

答案 5 :(得分:2)

Function.prototype.getName = function(fn) {
    if(Function.name || Function.prototype.name) return this.name;
    return this.toString().match(/^function\s+(\w+)\s*\(/)[1];
};

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

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

console.log(arguments.callee)

console.debug(arguments.callee)

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