在严格模式下获取当前函数名
Posted
技术标签:
【中文标题】在严格模式下获取当前函数名【英文标题】:Get current function name in strict mode 【发布时间】:2016-11-20 23:40:03 【问题描述】:我需要将当前函数名作为字符串记录到我们的日志工具。但是arguments.callee.name
只能在松散模式下工作。如何获取"use strict"
下的函数名?
【问题讨论】:
如果你能够修改函数的主体来添加日志代码,你不能硬编码函数名吗?如果您可以从属性中读取它,您会有什么优势? @nnnnnn 有人不断重命名函数但忘记更新日志行。 【参考方案1】:出于记录/调试目的,您可以在记录器中创建一个新的Error
对象并检查其.stack
属性,例如
function logIt(message)
var stack = new Error().stack,
caller = stack.split('\n')[2].trim();
console.log(caller + ":" + message);
function a(b)
b()
a(function xyz()
logIt('hello');
);
【讨论】:
你的回答有点复杂,但说明了思路。 一个很好的答案@georg。请注意,[2]
仅与此示例相关,例如,如果您有一个包含三个父函数的堆栈,在这种情况下,我们必须将 2 更改为 3
@hamism: stack[2]
始终是调用记录器的函数,无论堆栈有多深。
现在这是一个非常好的主意 :)
这是一个聪明的记录/调试解决方案。但是,对于考虑在生产代码中使用此功能的其他人(在我的情况下,用于事件跟踪),请注意:“此功能是非标准的,不在标准轨道上。请勿在面向Web:它不会对每个用户都有效。实现之间也可能存在很大的不兼容性,并且将来的行为可能会发生变化。” (developer.mozilla.org/en-US/docs/Web/javascript/Reference/…)【参考方案2】:
您可以将函数绑定为其上下文,然后您可以通过this.name
property 访问其名称:
function x()
console.log(this.name);
x.bind(x)();
【讨论】:
这很聪明。 这个很巧妙,但是bind的效果是永久的,不能再改变this的值,会导致bug。 Perharps,x.call(x) 可能是一个更好的解决方案【参考方案3】:经过一点研究,这里是一个很好的解决方案:
function getFnName(fn)
var f = typeof fn == 'function';
var s = f && ((fn.name && ['', fn.name]) || fn.toString().match(/function ([^\(]+)/));
return (!f && 'not a function') || (s && s[1] || 'anonymous');
function test()
console.log(getFnName(this));
test = test.bind(test);
test(); // 'test'
来源:https://gist.github.com/dfkaye/6384439
【讨论】:
但这在函数内部不起作用,除非您已经拥有对该函数的引用。 OP 要求替换arguments.callee.name
...【参考方案4】:
基于@georg 解决方案,这个只返回函数名。请注意,如果从匿名函数调用它可能会失败
function getFncName()
const stackLine = (new Error())!.stack!.split('\n')[2].trim()
const fncName = stackLine.match(/at Object.([^ ]+)/)?.[1]
return fncName
function Foo()
console.log(getFncName()) // prints 'Foo'
【讨论】:
这只适用于基于 Chromium 的浏览器【参考方案5】:动态检索函数名称 [如魔术变量] 的简单解决方案是使用作用域变量和 Function.name 属性。
function foo()
alert (a.name);
; let a = foo
function foo2()
alert(a.name)
; let a = foo2
;
foo();//logs foo
foo2();//logs foo2
注意:嵌套函数不再是源元素,因此不会被提升。此外,此技术不适用于匿名函数。
【讨论】:
以上是关于在严格模式下获取当前函数名的主要内容,如果未能解决你的问题,请参考以下文章