严格模式下获取当前函数名
Get current function name in strict mode
我需要将当前函数名称作为字符串记录到我们的日志工具中。但是 arguments.callee.name
只适用于松散模式。如何获取"use strict"
下的函数名?
经过一番研究,这里有一个很好的解决方案:
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'
出于 logging/debugging 目的,您可以在记录器中创建一个新的 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');
});
您可以将函数绑定为它的上下文,然后您可以通过 this.name
属性:
访问它的名称
function x(){
console.log(this.name);
}
x.bind(x)();
建立在@georg 解决方案的基础上,这个 returns 只是函数名称。请注意,如果从匿名函数调用它可能会失败
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'
}
动态检索函数名称[如魔法变量]的一个简单解决方案是使用作用域变量,Function.name 属性.
{
function foo() {
alert (a.name);
}; let a = foo
}
{
function foo2() {
alert(a.name)
}; let a = foo2
};
foo();//logs foo
foo2();//logs foo2
注意:嵌套函数不再是源元素,因此不会提升。此外,此技术不适用于匿名函数。
如果(像我一样)你想在别处定义它并一般地调用它,你可以将代码作为字符串存储在全局某处或导入它,然后 eval()
它可以在任何地方访问当前函数名称。 (使用 eval 将上下文保留在调用点。)
肯定有一种方法可以不使用字符串来做到这一点,但无论如何。
SomeObject.whatFunc =
'const s = new Error().stack;' +
"const stackLine = new Error().stack.split('\n')[2].trim();" +
'const fncName = stackLine.match(/(?<=at )(.*)(?= \()/gm)[0];' +
'console.log(fncName);'
// Whereever you want the func name
function countBananas('weeee') {
eval(SomeObject.whatFunc)
// blah blah blah
}
countBananas() // logs 'countBananas'
我需要将当前函数名称作为字符串记录到我们的日志工具中。但是 arguments.callee.name
只适用于松散模式。如何获取"use strict"
下的函数名?
经过一番研究,这里有一个很好的解决方案:
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'
出于 logging/debugging 目的,您可以在记录器中创建一个新的 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');
});
您可以将函数绑定为它的上下文,然后您可以通过 this.name
属性:
function x(){
console.log(this.name);
}
x.bind(x)();
建立在@georg 解决方案的基础上,这个 returns 只是函数名称。请注意,如果从匿名函数调用它可能会失败
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'
}
动态检索函数名称[如魔法变量]的一个简单解决方案是使用作用域变量,Function.name 属性.
{
function foo() {
alert (a.name);
}; let a = foo
}
{
function foo2() {
alert(a.name)
}; let a = foo2
};
foo();//logs foo
foo2();//logs foo2
注意:嵌套函数不再是源元素,因此不会提升。此外,此技术不适用于匿名函数。
如果(像我一样)你想在别处定义它并一般地调用它,你可以将代码作为字符串存储在全局某处或导入它,然后 eval()
它可以在任何地方访问当前函数名称。 (使用 eval 将上下文保留在调用点。)
肯定有一种方法可以不使用字符串来做到这一点,但无论如何。
SomeObject.whatFunc =
'const s = new Error().stack;' +
"const stackLine = new Error().stack.split('\n')[2].trim();" +
'const fncName = stackLine.match(/(?<=at )(.*)(?= \()/gm)[0];' +
'console.log(fncName);'
// Whereever you want the func name
function countBananas('weeee') {
eval(SomeObject.whatFunc)
// blah blah blah
}
countBananas() // logs 'countBananas'