获取自身内部的类函数名称

Posted

技术标签:

【中文标题】获取自身内部的类函数名称【英文标题】:Get the class function name within itself 【发布时间】:2013-10-07 11:49:33 【问题描述】:

我正在尝试使用 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] : "";

类名正确返回,但函数返回为“Function”。

【问题讨论】:

How do I get the name of an object's type in JavaScript? 或 Get an objects Class name at runtime in TypeScript 的可能重复 是 log4javascript 的绝对类型输入吗?我一直在等待那些! 我自己写的。将上传到存储库,但没有时间编写所需的测试类。 如果您想要我的副本或想要这样做,那么如果您愿意,我会通过电子邮件发送给您。 Tim,很想掌握 log4javascript 的类型。你有它们吗?无法在您的个人资料中看到电子邮件地址。 【参考方案1】:

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

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

这里toString会给你:

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

你可以看到function () 之间没有函数名。

你可以做的是创建一个内联函数(使用很棒的粗箭头,例如return getName(()=&gt;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

【讨论】:

有效。不过,对于使用表达式将其偷偷摸摸并不是很兴奋。我一直在尝试使用堆栈跟踪来获取前一个函数(所以有一个 GetCurrentName() 函数),创建一个错误并拉取调用堆栈的顶部。 codeovertones.com/2011/08/… 可能我的解决方案也好不了多少,也不知道会不会浪费资源。【参考方案2】:

我最终制作了两个函数。 1 代表当前栈顶方法,其他代表类型名称。

  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] : "";
  

【讨论】:

注意error.stack在不同的浏览器中是不同的

以上是关于获取自身内部的类函数名称的主要内容,如果未能解决你的问题,请参考以下文章

访问自身内部的匿名函数实例

名称空间

python名称空间

函数名称空间与作用域

python获取函数名

php 怎么获取当前函数名称 ?