typescript 从打字稿方法中获取方法名称

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/45744765/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:49:39  来源:igfitidea点击:

Get method name from within a typescript method

javascripttypescript

提问by Anand

I want to get the name of the current method from within an instance method of a class in Typescript.

我想从 Typescript 中类的实例方法中获取当前方法的名称。

(Pseudocode, doesn't work):

(伪代码,不起作用):

class Foo {
    bar() {
        console.log(something); //what should something be?
    }
}

new Foo().bar();

I expect 'something' to return 'bar'. I realize that thiscan give me the class, and I could somehow get the class and its attributes from it, but I do not know how to get 'this function' (i.e, the method bar, not the class Foo).

我希望“某事”返回“酒吧”。我意识到this可以给我类,我可以以某种方式从中获取类及其属性,但我不知道如何获取“此函数”(即方法栏,而不是类 Foo)。

I have seen several other questions related to finding the class name, etc. but not one that addresses getting the current method name.

我已经看到其他几个与查找类名等相关的问题,但没有一个解决获取当前方法名称的问题。

回答by Cristi Mihai

Besides the arguments.callee.namethere is no straightforward way of getting this.

除此之外,arguments.callee.name没有直接的方法可以得到这个。

I propose 2 other methods:

我提出了另外两种方法:

Use decorators to inject the method name:

使用装饰器注入方法名:

function annotateName(target, name, desc) {
    var method = desc.value;
    desc.value = function () {
        var prevMethod = this.currentMethod;
        this.currentMethod = name;
        method.apply(this, arguments);
        this.currentMethod = prevMethod;   
    }
}

class Foo {
    currentMethod: string;

    @annotateName
    bar() {
        alert(this.currentMethod);
        this.tux();
        alert(this.currentMethod);
    }

    @annotateName
    tux() {
        alert(this.currentMethod);
    }
}

new Foo().bar();

The downside is that you have to annotate all the functions you want to get the name from. You could instead just annotate the class and in the decorator you would iterate over all prototype functions and apply the same idea.

缺点是您必须注释所有要从中获取名称的函数。您可以改为只对类进行注释,然后在装饰器中迭代所有原型函数并应用相同的想法。



My second option is not standardised and need more care to get consistent results across browsers. It relies on creating an Error object and getting it's stacktrace.

我的第二个选项没有标准化,需要更加小心才能在浏览器中获得一致的结果。它依赖于创建一个 Error 对象并获取它的堆栈跟踪。

class Foo {
    bar() {
        console.log(getMethodName());    
    }
}

function getMethodName() {
    var err = new Error();
    return /at \w+\.(\w+)/.exec(err.stack.split('\n')[2])[1] // we want the 2nd method in the call stack

}

new Foo().bar();

回答by Slai

Not sure if this would help, but:

不确定这是否有帮助,但是:

class Foo {
    bar() {
        console.log(Object.getOwnPropertyNames(Foo.prototype)); // ["constructor", "bar"]
    }
}

new Foo().bar();

回答by Oleksii Shevchuk

for class name - Foo.namefor method name - this.bar.name

对于类名 -Foo.name对于方法名 -this.bar.name

回答by William Herrmann

Just to answer the question with another interesting take, you could do (but shouldn't do) something like this:

只是用另一个有趣的方式回答这个问题,你可以做(​​但不应该做)这样的事情:

class Foo {
    constructor(private http: HttpClient) {

        const apiUrl = 'http://myapi.com/api/';

        {
            const functionName = 'getBar';
            this[functionName] = function () {
                return http.get(apiUrl + functionName);
            }
        }

        {
            const functionName = 'postBar';
            this[functionName] = function () {
                return http.get(apiUrl + functionName);
            }
        }

        {
            const functionName= 'putBar';
            this[functionName] = function () {
                return http.get(apiUrl + functionName);
            }
        }

        {
            const functionName= 'deleteBar';
            this[functionName] = function () {
                return http.get(apiUrl + functionName);
            }
        }
    }
}

It certainly is not an elegant solution, and I can't really imagine a good use case for doing something like this, as I'm pretty sure the compiler doesn't recognize new Foo(http).deleteBar(). Maybe someone can come up with an elegant solution with this idea, I'll leave that as an experiment for someone.

这当然不是一个优雅的解决方案,我真的无法想象一个很好的用例来做这样的事情,因为我很确定编译器不会识别new Foo(http).deleteBar(). 也许有人可以用这个想法提出一个优雅的解决方案,我会把它留给某人做实验。

But with this pattern (if you employ some kind of devops scaffolding or "strong copy-paste skills") you can always access your method's name via functionName

但是使用这种模式(如果您使用某种 DevOps 脚手架或“强大的复制粘贴技能”),您始终可以通过以下方式访问您的方法名称 functionName

回答by Christian Ivicevic

Keep in mind that during compilation and minification you might lose the actual name of what you're trying to use. You might consider looking into the ts-nameofbabel macro that reads the name of virtually anything during compilation and returns it's actual string representation.

请记住,在编译和缩小期间,您可能会丢失您尝试使用的实际名称。您可能会考虑查看ts-nameofbabel 宏,该宏在编译期间读取几乎所有内容的名称并返回它的实际字符串表示形式。