nodejs怎么在函数体内访问该函数的函数名?
发布于 6 年前 作者 gyj1278 6817 次浏览 来自 问答

例如: ` function test(){ console.log('打印该函数名test!') } `

21 回复

函数是你写的啊,你直接打印不就好了吗

测试回复 不好意思

@JacksonTian 比如说这个函数发生了错误,我要记log,像这样logger.error(message:该函数发生错误,method:'${test}')。如果像这样的log需要在很多个函数中记呢?每次都拷贝函数名也行,但是有点麻烦。

@Binaryify 这个可以,这个应该不会有风险吧?

@Binaryify 刚才试了一下,eslint检查不通过,不建议使用这个方法,因为该方法在ECMAScript 5中是被禁止使用的。https://eslint.org/docs/rules/no-caller

直接在error对象的栈里找就可以了

function getFunctionName(){
  const s = (new Error()).stack;
  const e = /at getFunctionName[^\n]*\n\s*at (\S+)/.exec(s);
  console.log(`函数名:${e[1]}`);
}   

function test() {
	getFunctionName();
}

test(); // 函数名:test

记log的话还是建议把整个Error记下来

这种想法是不被严格模式下支持的,因为影响优化,建议采纳楼上的方法。

@dislido 谢谢,这种做法常用吗? new Error() 的机制只要不变,是可以的。

@gyj1278 不常用,很少有需要动态获取当前函数名的情况,非要这么做的话我目前只能想到这个办法

上面的方法只是写个例子,实际上还要考虑一些特殊情况

比如匿名函数没有函数名,箭头函数会获取为’__dirname’之类的问题

参考http://nodejs.cn/api/errors.html#errors_error_stack

@dislido new Error 实际上是有性能损耗的。如果不是真正 Error 级别的日志,这么搞就是浪费性能。

@galaxycubic 被你和上面的回答逗乐了,哈哈 饶了一大圈,还是你的最简单又靠谱 上面都是开玩笑,下面才是正解,应该满足你的要求(上午没时间写,下午想起来就写一下) 假设你的要运行的方法是method1,method2

class A{
    method1(a,b)
    {
        console.log(`a+b=${a+b}`);
        console.log("no error,method1");
    }

    method2()
    {
        throw "no error,method2";
    }
}


let a = new Proxy(new A(),{
    get: function (target, key){
        return function(...arg){
            try{
                target[key](...arg);
            } catch(err){
                console.log(`message:该函数发生错误,method:'${key}',error:'${err}'`);
            }
        };
    }
});

a.method1(111,222);
a.method2();

来自酷炫的 CNodeMD

针对上面的答案: 如果你的是原型链或或者是异步函数,照着改就行了。满足你的需求,切面才是王道 不要说取个函数名,就算要记录运行的函数运行时间都行,哈哈 大家的野路子有意思,哈哈😄😄😄

console.trace

console.trace('Show me');
// Prints: (stack trace will vary based on where trace is called)
//  Trace: Show me
//    at repl:2:9
//    at REPLServer.defaultEval (repl.js:248:27)
//    at bound (domain.js:287:14)
//    at REPLServer.runBound [as eval] (domain.js:300:12)
//    at REPLServer.<anonymous> (repl.js:412:12)
//    at emitOne (events.js:82:20)
//    at REPLServer.emit (events.js:169:7)
//    at REPLServer.Interface._onLine (readline.js:210:10)
//    at REPLServer.Interface._line (readline.js:549:8)
//    at REPLServer.Interface._ttyWrite (readline.js:826:14)

https://nodejs.org/dist/latest-v8.x/docs/api/console.html#console_console_trace_message_args 可惜还是走了error流程的write,写往stderr,用了Error.captureStackTrace静态方法

image.png

觉得牛逼,请 call 666.

@gyj1278 打印调用栈呀。error.stack

回到顶部