繁体   English   中英

通过匿名函数获取变量的名称

[英]getting the name of a variable through an anonymous function

是否可以找到匿名函数的名称?

例如,试图找到一种方法来警告anonyFufindMe在这段代码http://jsfiddle.net/L5F5N/1/

function namedFu(){
    alert(arguments.callee);
    alert(arguments.callee.name);
    alert(arguments.callee.caller);
    alert(arguments.caller);
    alert(arguments.name);
}

var anonyFu = function() {
    alert(arguments.callee);
    alert(arguments.callee.name);
    alert(arguments.callee.caller);
    alert(arguments.caller);
    alert(arguments.name);
}

var findMe= function(){ 
    namedFu();
    anonyFu();
}
findMe();

这是一些内部测试,因此不需要跨浏览器。 事实上,即使我必须安装一个插件,我也会很高兴。

怀疑它是否有可能以你的方式获得它。 对于初学者,如果添加了一行

var referenceFu = anonyFu;

您希望能够记录哪些名称? 他们都只是参考。

但是 - 假设您有能力更改代码 - 这是有效的javascript:

var anonyFu = function notActuallyAnonymous() {
    console.log(arguments.callee.name);
}

这会记录"notActuallyAnonymous" 因此,您可以在不破坏代码的情况下为您有兴趣检查的所有匿名函数添加名称。

不确定这有用,但这都是我得到的。

您可以使用arguments.callee以编程方式,甚至是未命名的匿名函数,从其中识别函数的任何属性。 所以你可以用这个简单的技巧来识别这个功能:

每当你创建一个函数时,为它分配一些属性,你可以用它来识别它。

例如,始终创建一个名为id的属性:

var fubar = function() {
   this.id = "fubar";
   //the stuff the function normally does, here
   console.log(arguments.callee.id);
}

arguments.callee本身就是函数,因此该函数的任何属性都可以像上面的id一样被访问,甚至是你自己分配的属性。

Callee正式被弃用,但几乎在所有浏览器中仍然有效,并且在某些情况下仍然没有替代品。 你不能在“严格模式”下使用它。

当然,您也可以命名匿名函数,例如:

var fubar = function foobar() {
   //the stuff the function normally does, here
   console.log(arguments.callee.name);
}

但显然不那么优雅,因为你不能(在这种情况下)在两个地方都将它命名为fubar; 我不得不将实际名称设为foobar。

如果你的所有函数都有描述它们的注释,你甚至可以抓住它,如下所示:

var fubar = function() {
   /* 
      fubar is effed up beyond all recognition 
      this returns some value or other that is described here
    */
   //the stuff the function normally does, here
   console.log(arguments.callee.toString().substr(0, 128);
}

请注意,您还可以使用argument.callee.caller来访问调用当前函数的函数。 这使您可以从外部访问函数的名称(或属性,如id或文本中的注释)。

你这样做的原因是你想找出所谓的函数。 这可能是您首先想要以编程方式查找此信息的原因。

因此,如果上面的一个fubar()示例调用了以下函数:

var kludge = function() {
   console.log(arguments.callee.caller.id); // return "fubar" with the first version above
   console.log(arguments.callee.caller.name); // return "foobar" in the second version above
   console.log(arguments.callee.caller.toString().substr(0, 128);
     /* that last one would return the first 128 characters in the third example, 
        which would happen to include the name in the comment. 
        Obviously, this is to be used only in a desperate case, 
        as it doesn't give you a concise value you can count on using)
     */
}

我将补充一点,如果您知道该函数在哪个对象中,那么您可以添加代码 - 对于该对象或通常添加到对象原型 - 这将获得基于值的关键名称。

Object.prototype.getKeyByValue = function( value ) {
    for( var prop in this ) {
        if( this.hasOwnProperty( prop ) ) {
             if( this[ prop ] === value )
                 return prop;
        }
    }
}

然后你可以使用

THAT.getKeyByValue(arguments.callee.caller);

使用此方法一次用于调试,其中涉及项目中涉及大多数函数在一个对象中的性能测试。 不想在代码中用任何其他方式命名所有函数或双重名称,需要计算每个函数运行的时间 - 所以这样做加上函数启动时的堆栈推送时间和结束时弹出。

为什么? 为每个函数添加非常少的代码,并为每个函数添加相同的代码,以便在控制台上进行测量和调用列表。 这是暂时的。

THAT._TT = [];
THAT._TS = function () {
  THAT._TT.push(performance.now());
}
THAT._TE = function () {
  var tt = performance.now() - THAT._TT.pop();
  var txt = THAT.getKeyByValue(arguments.callee.caller);
  console.log('['+tt+'] -> '+txt);
};


THAT.some_function = function (x,y,z) {
    THAT._TS();
    // ... normal function job
    THAT._TE();
}

THAT.some_other_function = function (a,b,c) {
    THAT._TS();
    // ... normal function job
    THAT._TE();
}

不是很有用,但也许它可以帮助在类似情况下遇到类似问题的人。

arguments.callee它被弃用了,因为MDN声明:

你应该避免使用arguments.callee()并给每个函数(表达式)一个名称。

换一种说法:

[1,2,3].forEach(function foo() {
  // you can call `foo` here for recursion
})

如果您想要的是为分配给变量的匿名函数命名,那么假设您正在调试代码并且想要跟踪此函数的名称,那么您可以将其命名为两次,这是一种常见模式:

var foo = function foo() { ... }

除了在MDN文档中指定的评估案例之外,我想不出你想要使用arguments.callee的任何其他情况。

根据定义, 匿名函数没有name 但是,如果你想要求函数表达式:是的,你可以命名它们

不,在运行时期间无法获取变量的名称(引用该函数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM