获取自身内的类函数名称

Get the class function name within itself

本文关键字:类函数 获取      更新时间:2023-09-26

我正在尝试使用log4javascript在我的打字稿程序中设置日志记录。

但是我不知道如何使用反射(而不是手动键入)检索函数名称。

理想情况下,我想模仿我在C#所做的事情:

public class Foo 
{
    private static readonly log4net.ILog logger = log4net.LogManager.GetLogger(typeof(Foo));
    public Foo()
    {
    }
    public FooMethod()
    {
        try {
            logger.Logger.Log(this.GetType(), log4net.Core.Level.Trace, "Entering" + MethodBase.GetCurrentMethod().Name, null);
            // code
        }
        catch (e) {
            logger.Logger.Log(this.GetType(), log4net.Core.Level.Debug, ex.Message, null);
        }
        finally {
            logger.Logger.Log(this.GetType(), log4net.Core.Level.Trace, "Exiting" + MethodBase.GetCurrentMethod().Name, null);
        }
    }
}

如何在Typescript中执行此操作?我所能做的就是获取类名。

class Foo {
    private static logger: log4javascript.Logger = log4javascript.getLogger(getName(Foo));
    constructor() {
    }
    FooFunction() {
        try {
            SymDataSource.logger.trace("Entering: " + getName(Foo.prototype.FooFunction));
            // code
        } catch (e) {
            SymDataSource.logger.debug("Exception: " + getName(Foo.prototype.FooFunction), e);
        } finally {
            SymDataSource.logger.trace("Exiting: " + getName(Foo.prototype.FooFunction));
        }
    }
}
function getName(obj: any): string {
   if (obj.name) {
       return obj.name;
   }
   var funcNameRegex = /function (.{1,})'(/;
   var results = (funcNameRegex).exec((<any> obj).constructor.toString());
   return (results && results.length > 1) ? results[1] : "";
}

类名正确返回,但函数返回为"函数"。

对于成员函数,由于创建原型函数的方式,实际上无法使用简单的toString解析方法,例如:

Foo.prototype.FooFunction = function () {
    return getName(this.FooFunction);
};

在这里,toString会给你:

function () {
    return getName(this.FooFunction);
};

并且您可以看到函数名称在function () {之间不存在。

您可以做的是创建一个内联函数(使用令人敬畏的胖箭头,例如 return getName(()=>this.FooFunction); ) 并解析此本地函数体以查找函数名称。请注意,通过这种方式,它仍然是 TypeSafe,如果您进行重命名重构,则不会有不同步的魔术字符串。所以完整的实现变成:

class Foo { 
    static className = getName(Foo);    
    constructor() {
    }
    FooFunction() {        
            return getName(()=>this.FooFunction);            
    }
}
function getName(obj: any): string {    
    if (obj.name) {
        return obj.name;
    }
    var funcNameRegex = /function (.{1,})'(/;   
    var results = (funcNameRegex).exec(obj.toString());
    var result = results && results.length > 1 && results[1];
    // Check to see custom implementation
    if(!result){
        funcNameRegex = /return _this.(.*);/;
        results = (funcNameRegex).exec(obj.toString());
        result = results && results.length > 1 && results[1];
    }
    return result || "";
}
console.log(Foo.className);
var foo = new Foo();
console.log(foo.FooFunction());

这将输出:

Foo
FooFunction

我最终做了两个函数。 1 表示堆栈中的当前 top 方法,其他表示类型名称。

  export function getName(): string {
     var result: string = "";
     var error: any = new Error("getStack");
     var stack: string[] = error.stack
        .replace(/^[^'(]+?['n$]/gm, '') // Remove first useless line
        .replace(/^'s+at's+/gm, '') // Remove 'at'
        .replace(/^Object.<anonymous>'s*'(/gm, '{anonymous}()@') // Replace Object.<anon> with {anon}
        .replace(/'s'(.*:[0-9]+:[0-9]+')/gm, '') // Remove filename, col and row
        .split(''n');
     return stack[1]; // Previous method
  }
  export function getType(obj: any): string {
     if (obj.name) {
        return obj.name;
     }
     var results = /function (.{1,})'(/.exec(obj.constructor.toString());
     return (results && results.length > 1) ? results[1] : "";
  }