【问题标题】:Get function name in JavaScript在 JavaScript 中获取函数名
【发布时间】:2011-03-11 20:52:37
【问题描述】:

有谁知道是否有办法获取 JavaScript 函数名。例如,我有一个类似

的函数
function test1(){
alert(1);
}

我的头部有它。然后我创建一个对象 obj1 并将我的函数放在那里

obj1.func = test1;

当我在 obj1 对象中调用一个方法时,除了解析函数的源 (this.func.toString()) 之外,我有什么方法可以在该方法中获取我的函数名 (test1)。

【问题讨论】:

  • 为什么需要函数名?

标签: javascript


【解决方案1】:
function test() {  alert(arguments.callee.name); } 
b = test; 
b();

输出“测试”(在 Chrome、Firefox 和可能的 Safari 中)。但是,arguments.callee.name 只能从函数内部获得。

如果您想从 outside 获取名称,您可以将其解析为:

b.toString();

但我认为函数对象的 name 属性可能是您所需要的:

alert(b.name);

但这似乎不适用于 IE 和 Opera,因此您只能在这些浏览器中手动解析它。

【讨论】:

  • 两件事,这既是deprecated,也不能在 IE 中工作,即使是 IE8 :)
  • @Nick Craver: callee 作为Function.arguments 的属性已弃用,但作为arguments 的属性保留:developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
  • @Nick:哦,我知道 JScript 5.5 没有实现 Javascript 1.5。我只是想知道为什么arguments.callee.name 在 IE 5.5+ 中不起作用。我在 IE 6 中测试了它的代码。确实,它不起作用。然后我测试了jsfiddle.net/guxRA/2,看来IE 6 生成的函数源代码为arguments.callee。多么有趣。
  • 更重要的是,IE 不支持 Function 对象的非标准 name 属性。
  • FYI function.name 是“ECMAScript 2015 (ES6) 标准的一部分”,所以它应该是未来的证明(但今天可能并不适用于任何地方)。见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
【解决方案2】:

ES2015 之前,没有标准的方法来获取函数的名称。大多数当前浏览器支持Function 对象上的name 属性,该属性在 ES2015 之前是非标准的,但当前版本的 IE 不支持。如果您需要支持 IE,唯一的选择是尝试从函数的字符串表示中解析名称,这不是一个好主意。这里有一个(长时间)讨论:http://groups.google.com/group/comp.lang.javascript/browse_frm/thread/b85dfb2f2006c9f0

【讨论】:

  • 有什么理由不在调试环境中使用它?
  • @ChrisDutrow:取决于您的要求。问题是在今天的浏览器中可以使用的东西在明天可能无法使用。
  • 怎么样?如果历史证明了什么,那么情况恰恰相反:今天有效的东西是唯一保证在明天的浏览器中也有效的东西。任何以向后不兼容的方式更改、破坏现有网站的浏览器都将明智地放弃市场份额。
  • 这就是 W3C 试图弃用 等标签的尝试失败的原因。这也是为什么表单字段上的名称属性或“form.myField.value”等表达式仍然有效的原因。这就是 IANA 愚蠢地扼杀 text/javascript mime 类型的尝试注定要失败的原因。你不能弃用/废弃/杀死那些在网络上积极使用的东西。
  • @DanRandolph:在我看来,这在 2010 年是一个很好的答案,但现在有点过时了,因为 name 属性现在在 ES2015 中已标准化。但是,IE 仍然不支持name,所以它仍然是相关的。
【解决方案3】:

我正在尝试的一种有趣的方式是如下声明:

var test1 = function test1(){
    alert(1);
};

这有点 hacky,但最终发生的是 test1 是一个包含 [Function: test1] 对象的局部变量。

当您使用基于它的代码时会发生以下情况:

test1(); //runs the function as expected
console.log(test1.name); //prints 'test1'

因此,如果您执行以下操作:

obj1.func = test1;

然后您就可以引用obj1.func.name,它会返回'test1'

【讨论】:

    【解决方案4】:

    这是我用来将类名放入错误消息中的方法。它包含获取函数名称的代码,适用于大多数浏览器。

    显然,没有标准的方法总是有效的,因此您应该始终提供一个可以在没有找到其他名称时使用的名称。

    var nameFromToStringRegex = /^function\s?([^\s(]*)/;
    
    /**
     * Gets the classname of an object or function if it can.  Otherwise returns the provided default.
     *
     * Getting the name of a function is not a standard feature, so while this will work in many
     * cases, it should not be relied upon except for informational messages (e.g. logging and Error
     * messages).
     *
     * @private
     */
    function className(object, defaultName) {
        var result = "";
        if (typeof object === 'function') {
            result = object.name || object.toString().match(nameFromToStringRegex)[1];
        } else if (typeof object.constructor === 'function') {
            result = className(object.constructor, defaultName);
        }
        return result || defaultName;
    }
    

    【讨论】:

    • 它不适用于 Chrome 版本 59.0.3071.115(官方构建)(64 位)/* ReferenceError: object_someMethod is not defined */ var Enforcer = function () { try { object_someMethod; } catch (e) { console.log(e); } }; Enforcer.query = function () { try { object_someMethod; } catch (e) { console.log(e); } }
    • /* ReferenceError: object_someMethod is not defined */ var Enforcer = function Enforcer() { try { object_someMethod; } catch (e) { console.log(e); } }; Enforcer.query = function () { try { object_someMethod; } catch (e) { console.log(e); } }
    【解决方案5】:

    您可以将您的函数转换为字符串 (fn + ''),然后在 空格和左括号 /\s|\(/ 处拆分它。

    var getFunctionName = function (fn) {
       return (fn + '').split(/\s|\(/)[1];
    };
    

    【讨论】:

    • 它不适用于 Chrome 版本 59.0.3071.115(官方构建)(64 位)// ReferenceError: object_someMethod is not defined var Enforcer = function () { try { object_someMethod; } catch (e) { console.log(e); } }; Enforcer.query = function () { try { object_someMethod; } catch (e) { console.log(e); } }
    【解决方案6】:

    这可能是最好的方法:

    var myfunc = function () {};
    var funcName = myfunc.constructor.name;
    

    这可以在函数执行之外完成,您可以在浏览器控制台的上下文中进行检查。

    编码愉快!

    【讨论】:

    • 它不适用于 Chrome 版本 59.0.3071.115(官方构建)(64 位),打印 funcName 输出“功能”
    【解决方案7】:

    最好的办法是:

    function functionName(fun) {
      var ret = fun.toString();
      ret = ret.substr('function '.length);
      ret = ret.substr(0, ret.indexOf('('));
      return ret;
    }
    

    注意:使用Function.caller 是非标准的,在严格模式下禁止使用arguments.callee

    【讨论】:

    • 它很酷,但如果你在函数内,你不会得到函数名
    猜你喜欢
    • 2011-09-29
    • 2011-01-10
    • 1970-01-01
    • 2012-04-06
    • 1970-01-01
    • 1970-01-01
    • 2021-08-13
    • 1970-01-01
    相关资源
    最近更新 更多