获取自身内部的类函数名称
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(()=>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在不同的浏览器中是不同的以上是关于获取自身内部的类函数名称的主要内容,如果未能解决你的问题,请参考以下文章