Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
141
rated 0 times [  148] [ 7]  / answers: 1 / hits: 18622  / 8 Years ago, thu, june 30, 2016, 12:00:00

For anyone viewing this, this question is similar to the following:



How do I get the name of an object's type in JavaScript?

Get an object's class name at runtime in TypeScript



However it is different in a few regards.



I'm looking to get the name of method that belongs to a class and store it in a variable in TypeScript / JavaScript.

Take a look at the following setup:



class Foo {

bar(){
// logic
}

}


The above is valid TypeScript and I would like to create a method in a different class that will return me the name of the bar() method, i.e bar

eg:



class ClassHelper {

getMethodName(method: any){
return method.name; // per say
}

}


I would then like to be able to use the ClassHelper in the following way:



var foo = new Foo();
var barName = ClassHelper.getMethodName(foo.bar); // bar


I've looked at a lot of posts, some suggest using the following:



var funcNameRegex = /function (.{1,})(/;   
var results = (funcNameRegex).exec(obj.toString());
var result = results && results.length > 1 && results[1];


but this fails as my methods do not begin with function

another suggestion was:



public getClassName() {
var funcNameRegex = /function (.{1,})(/;
var results = (funcNameRegex).exec(this[constructor].toString());
return (results && results.length > 1) ? results[1] : ;
}


This only returns the class name however and from reading posts, it seems using constructor can be unreliable.



Also, when I've debugged the code using some of these methods, passing in the method like so: ClassHelper.getMethodName(foo.bar); will result in the parameter being passed if the method takes one, eg:



class Foo {

bar(param: any){
// logic
}

}

var foo = new Foo();
var barName = ClassHelper.getMethodName(foo.bar); // results in param getting passed through


I've been struggling with this for a while, if anyone has any information on how I can solve this it would be greatly appreciated.



My .toString() on the method passed in returns this:



.toString() = function (param) { // code }


rather than:



.toString() = function bar(param) { // code }


and according to MDN it isn't supposed to either:




That is, toString decompiles the function, and the string returned includes the function keyword, the argument list, curly braces, and the source of the function body.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString#Description



More From » regex

 Answers
115

I found a solution. I'm not sure how efficient and reusable it is, but it worked in multiple test cases, included nested methods, eg Class -> Class -> Method



My solution:



class ClassHelpers {
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];

if(!result){
funcNameRegex = /return .([^;]+)/;
results = (funcNameRegex).exec(obj.toString());
result = results && results.length > 1 && results[1].split(.).pop();
}

return result || ;
}
}


class Foo {

bar(param: any){
// logic
}

}

var foo = new Foo();
var barName = ClassHelper.getMethodName(() => foo.bar);


The lambda notation ClassHelper.getMethodName(() => foo.bar); was key to getting this to work as it allowed the .toString() to contain return foo.bar;



The next thing I had to do was to extract the method call from the .toString() then I used array and string functions to return the last substring which inevitably is the method name.



Like I said, it's probably not the most elegant solution but it has worked and even worked for nested methods



NOTE: You can replace the lambda function with a regular anonymous function



var foo = new Foo();
var barName = ClassHelper.getMethodName(function() { return foo.bar; });

[#61570] Tuesday, June 28, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
claudia

Total Points: 734
Total Questions: 106
Total Answers: 113

Location: Sweden
Member since Fri, Apr 16, 2021
3 Years ago
;