从typescript方法中获取方法名称

时间:2017-08-17 20:51:32

标签: javascript typescript

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

(伪代码,不起作用):

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

new Foo().bar();

我期待'某事'返回' bar'。我意识到this可以给我上课,我可以通过某种方式从中获得课程及其属性,但我不知道如何获得这个功能' (即方法栏,而不是Foo类)。

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

6 个答案:

答案 0 :(得分:11)

除了arguments.callee.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();

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

我的第二个选项不是标准化的,需要更多关注才能在浏览器中获得一致的结果。它依赖于创建一个Error对象并获得stack跟踪。

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();

答案 1 :(得分:2)

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

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

new Foo().bar();

答案 2 :(得分:1)

类别名称-Foo.name 方法名称-this.bar.name

答案 3 :(得分:1)

请记住,在编译和缩小过程中,您可能会丢失要使用的实际名称。您可以考虑查看ts-nameof babel宏,该宏在编译过程中读取几乎所有内容的名称并返回其实际的字符串表示形式。

答案 4 :(得分:0)

只需以另一种有趣的方式回答问题,您就可以(但不应该)这样做:

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);
            }
        }
    }
}

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

但是采用这种模式(如果您使用某种devops支架或“强大的复制粘贴技能”),您始终可以通过functionName

访问方法的名称

答案 5 :(得分:0)

我也在寻找解决方案,试试这个:

class Foo {
  bar() {
      console.log(this.bar.name); // <-- Print out the function name.
  }
}
  
new Foo().bar(); 

如果你改变了函数名,但忘记更新控制台语句,你会得到一个错误。