Col*_*lum 8 javascript regex typescript
对于查看此内容的任何人,此问题类似于以下内容:
如何在JavaScript中获取对象类型的名称?
在TypeScript中运行时获取对象的类名
然而,在一些方面它是不同的.
我希望得到属于类的方法的名称,并将其存储在TypeScript/JavaScript中的变量中.
看看以下设置:
class Foo {
bar(){
// logic
}
}
Run Code Online (Sandbox Code Playgroud)
以上是有效的TypeScript,我想在不同的类中创建一个方法,它将返回bar()方法的名称,"bar"
例如:
class ClassHelper {
getMethodName(method: any){
return method.name; // per say
}
}
Run Code Online (Sandbox Code Playgroud)
我希望能够以ClassHelper下列方式使用:
var foo = new Foo();
var barName = ClassHelper.getMethodName(foo.bar); // "bar"
Run Code Online (Sandbox Code Playgroud)
我看过很多帖子,有些建议使用以下内容:
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(obj.toString());
var result = results && results.length > 1 && results[1];
Run Code Online (Sandbox Code Playgroud)
但由于我的方法没有从function
另一个建议开始,这失败了:
public getClassName() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec(this["constructor"].toString());
return (results && results.length > 1) ? results[1] : "";
}
Run Code Online (Sandbox Code Playgroud)
这只返回类名,但是从阅读帖子中看来,使用它constructor可能是不可靠的.
此外,当我使用其中一些方法调试代码时,传递方法如下:ClassHelper.getMethodName(foo.bar);如果方法采用一个方法,将导致传递参数,例如:
class Foo {
bar(param: any){
// logic
}
}
var foo = new Foo();
var barName = ClassHelper.getMethodName(foo.bar); // results in param getting passed through
Run Code Online (Sandbox Code Playgroud)
我一直在努力解决这个问题,如果有人有任何关于如何解决这个问题的信息,我将不胜感激.
我.toString()传入的方法返回:
.toString() = "function (param) { // code }"
Run Code Online (Sandbox Code Playgroud)
而不是:
.toString() = "function bar(param) { // code }"
Run Code Online (Sandbox Code Playgroud)
根据MDN,它不应该:
也就是说,toString反编译该函数,返回的字符串包括函数关键字,参数列表,花括号和函数体的源.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/toString#Description
我采纳了约翰·怀特的想法并对其进行了改进,使其适用于我能想到的每种情况。这种方法的优点是运行时不需要解析js代码。但有一种边缘情况,它根本无法推断出正确的属性名称,因为有多个正确的属性名称。
class Foo {
bar() {}
foo() {}
}
class ClassHelper {
static getMethodName(obj, method) {
var methodName = null;
Object.getOwnPropertyNames(obj).forEach(prop => {
if (obj[prop] === method) {
methodName = prop;
}
});
if (methodName !== null) {
return methodName;
}
var proto = Object.getPrototypeOf(obj);
if (proto) {
return ClassHelper.getMethodName(proto, method);
}
return null;
}
}
var foo = new Foo();
console.log(ClassHelper.getMethodName(foo, foo.bar));
console.log(ClassHelper.getMethodName(Foo.prototype, foo.bar));
console.log(ClassHelper.getMethodName(Foo.prototype, Foo.prototype.bar));
var edgeCase = { bar(){}, foo(){} };
edgeCase.foo = edgeCase.bar;
console.log(ClassHelper.getMethodName(edgeCase, edgeCase.bar));Run Code Online (Sandbox Code Playgroud)
我找到了解决方案。我不确定它的效率和可重用性如何,但它在多个测试用例中有效,包括嵌套方法,例如Class -> Class -> Method
我的解决方案:
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);
Run Code Online (Sandbox Code Playgroud)
lambda 表示法ClassHelper.getMethodName(() => foo.bar);是让它工作的关键,因为它允许.toString()包含return foo.bar;
我要做的下一件事是从其中提取方法调用,.toString()然后我使用数组和字符串函数返回最后一个子字符串,这不可避免地是方法名称。
就像我说的,它可能不是最优雅的解决方案,但它确实有效,甚至适用于嵌套方法
注意:您可以用常规匿名函数替换 lambda 函数
var foo = new Foo();
var barName = ClassHelper.getMethodName(function() { return foo.bar; });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8032 次 |
| 最近记录: |