如何获取JavaScript对象的方法名称?

3

我目前正在构建一个更大的对象,需要更快速和更具体地进行调试/检查值/结果/返回。

现在我想到了以下几点:

var myObject = {
    whatever: null,
    whereever: null,
    debug: false,

    someFunction: function( arg ) {
        // General - would output *all* logs for all object functions.
        // if ( true === myObject.debug )
        //  console.log( 'FunctionNameHere', arg );

        // More specific - would output *only* the log for the currently targeted function
        if ( 'FunctionName' === myObject.debug )
            console.log( 'FunctionNameHere', arg );
    },
};

这将使我能够简单地将对象变量debug定义为一个函数名称,并仅记录此部分。
唯一的问题是:我如何获取FunctionName/someFunction
附注:
  • console.log( arguments.callee ); 给出整个函数源代码。
  • console.log( arguments.callee.name ); 返回为空。
  • console.log( arguments.callee.toString() ); 返回为空。
  • console.log( arguments.caller ); 返回undefined
如果我查看整个对象的日志,我会看到prototype.name="Empty"等。因此,无法直接从对象中获取它。
谢谢!

一般来说,如果调试为 true,那么当执行 myObject 的任何函数时,您希望记录控制台消息,其中包括函数名称和参数? - kubetz
@dzejkej 不完全是这样。如果我将“debug”设置为函数名称,则只有同名fn的“log”应触发。这将允许我在每个函数中构建调试,并仅在需要/指定时触发它。 - kaiser
1
我看到你刚开始学习JS,意识到这对于新手来说可能有些高级。希望我没有冒犯你 : )。var x = y, a = b;var x = y; var a = b;以及var x, a; x = y; a = b;是相同的,只是变量声明和赋值方式不同而已。JS确实很有趣 ; )。 - kubetz
啊,好的。谢谢你的解释。并且不,你没有冒犯我 :) 因为我最初来自php,所以我错过了许多“基本”函数,比如array_filter等等。默认js循环和数组让我的生活变得有些困难。也许我还没有深入挖掘,或者我一直在错误的地方搜索 :P 顺便说一句:如果你有一个链接告诉我如何测量性能-非常感谢-我的代码到目前为止都可以工作,但是我不知道我的陷阱在哪里:) - kaiser
1
JS很小但灵活,大部分功能都在库里面。配置文件 - 这是一些与Chrome和Firefox有关的链接。这篇文章介绍了Chrome新功能的一个很好的视频。 - kubetz
显示剩余2条评论
3个回答

3
如果你想在debugtrue时记录每个函数,如果debug设置为函数名,则仅记录该函数。你不需要在每个函数中硬编码此内容。
您可以动态重写函数。这有点神奇,但更加灵活,您无需在添加更多函数或更改其名称时更改任何内容。 这里是工作代码。
for (var key in myObject) {
  // if the keys belongs to object and it is a function
  if (myObject.hasOwnProperty(key) && (typeof myObject[key] === 'function')) {
    // overwrite this function
    myObject[key] = (function() {
      // save the previous function
      var functionName = key, functionCode = myObject[functionName];
      // return new function that will write log message and run the saved function
      return function() {
        if (myObject.debug === true || myObject.debug === functionName) {
          console.log('I am function ' + functionName, ' with arguments: ', arguments);
        }
        functionCode(arguments);
      };
    })();
  }
}

谢谢您提供的函数。问题(我猜)是我的对象与 google.maps 一起使用,所以这会破坏一切,因为 latlng 在中间断开了... - kaiser
好的,已经在对象内部解决了。谢谢 - 标记为解决方案。 - kaiser

1

这是一个匿名函数,它没有名称,因此您无法像现在这样访问它。

如果您像这样声明它:

someFunction: function iNowHaveAName( arg )

根据您所使用的浏览器,可以以不同方式获取名称。

在支持的浏览器中,可以使用arguments.callee.name。(这是快速且无需性能的)

在不支持的浏览器中,您可以捕获异常并在堆栈跟踪中找到它:

try {
 i.dont.exist+=1;
}
catch(e) {
//play with the stacktrace here
}

这个方法很慢,而且性能开销很大 - 在生产代码中不要这样做 :)

请注意,arguments.callee已被弃用,并将在未来的JavaScript版本中删除。在ES5严格模式下已不可用。 - Phrogz
我刚开始学习JS,所以我不知道我可以像这样命名它们:someFunction: function iNowHaveAName。谢谢 +1 - kaiser
1
此外,有一种比回溯更好的获取名称的方法:function getName(f){ var match = /function (\w+)/.exec(f+""); return match && match[1]; } - Phrogz

1

如果一个函数没有名称,你就无法获取它。匿名函数——也就是你现在所拥有的——没有名称。将一个或多个变量或对象属性分配为引用函数值并不能给它命名。

考虑以下示例:

var a = [function(){}];
var b = a;
var c = a[0];

那个单一函数的“名称”是什么?a [0]b [0]c?为什么应该选择其中之一?

JavaScript没有任何方法允许您询问特定对象(包括函数)的所有引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接