在 JavaScript 中获取函数名称

IT技术 javascript
2021-01-26 09:31:59

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

function test1(){
alert(1);
}

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

obj1.func = test1;

当我调用 obj1 对象中的方法时,除了解析this.func.toString()函数的源 ( )外,我有没有办法在该方法中获取我的函数名称 (test1)

6个回答
function test() {  alert(arguments.callee.name); } 
b = test; 
b();

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

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

b.toString();

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

alert(b.name);

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

@Nick:哦,我知道 JScript 5.5 没有实现 Javascript 1.5。我只是想知道为什么arguments.callee.name不能在 IE 5.5+ 中工作。我在 IE 6 中测试了它的代码。确实,它不起作用。然后我测试了jsfiddle.net/guxRA/2,似乎 IE 6 为该函数生成了源代码arguments.callee多好笑。
2021-03-15 09:31:59
仅供参考 function.name 是“ECMAScript 2015 (ES6) 标准的一部分”,因此它应该是面向未来的(但今天可能不适用于所有地方)。参见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
2021-03-17 09:31:59
两件事,这既已弃用,又不适用于 IE,甚至 IE8 :)
2021-04-04 09:31:59
@Nick Craver:callee作为 的属性被弃用Function.arguments,但作为属性保留argumentsdeveloper.mozilla.org/en/Core_JavaScript_1.5_Reference/...
2021-04-12 09:31:59
更重要的是,IE 不支持对象的非标准name属性Function
2021-04-13 09:31:59

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

这就是 W3C 试图弃用 <b> 和 <i> 之类的标签失败的原因。这也是为什么诸如表单字段上的名称属性或“form.myField.value”之类的表达式仍然有效的原因。这就是为什么 IANA 试图杀死 text/javascript mime 类型的愚蠢尝试注定要失败。您不能弃用/过时/杀死在整个网络上积极使用的内容。
2021-03-14 09:31:59
有什么理由不在调试环境中使用它?
2021-03-16 09:31:59
@ChrisDutrow:取决于您的要求。问题是在今天的浏览器中有效的东西在明天的浏览器中可能无效。
2021-03-18 09:31:59
如何?如果历史已经证明了任何事情,那么情况恰恰相反:今天有效的东西是唯一保证在明天的浏览器中也能正常工作的东西。任何以向后不兼容的方式更改、破坏现有网站的浏览器,都将明智地自杀。
2021-04-05 09:31:59
@DanRandolph:在我看来,这是 2010 年的一个很好的答案,但现在有点过时了,因为该name属性现已在 ES2015 中标准化。但是,IE 仍然不支持,name因此它仍然相关。
2021-04-09 09:31:59

最好的做法是:

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

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

它很酷,但如果你在函数内,你就不会得到函数名
2021-04-11 09:31:59

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

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

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); } }
2021-03-26 09:31:59
/* 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); } }
2021-03-27 09:31:59

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

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'.