我正在用打字稿创建动态函数。在这些动态函数上,我想添加装饰器。实现此方案的最佳方法是什么?这有可能吗?
例如-想要实现这样的目标
product.videos
此外,如果我要创建多个动态函数,如何在其上添加装饰器?
例如
@decorator1
@decorator2
var dynamicFunction = new Function('a', 'b', 'return a + b');
alert(dynamicFunction(2, 3));
答案 0 :(得分:1)
不能将修饰符添加到直接函数中。从打字稿文档(https://www.typescriptlang.org/docs/handbook/decorators.html):
装饰器
装饰器是一种特殊的声明,可以附加到类上 声明,方法,访问器,属性或参数。装饰者使用表格 @expression,其中expression必须计算为将在处调用的函数 运行时,包含有关修饰声明的信息。
尝试时,您会发现它不是那样工作的,因为脚本编写的装饰器函数假定有一个类链接到要装饰的东西,如文档中所述。
但是,我不建议这样做,您可以在一个类中拥有所需的功能,那么将适用以下条件:
方法装饰器
在方法之前声明方法装饰器 宣言。装饰器应用于以下属性的描述符: 方法,可用于观察,修改或替换方法 定义。方法修饰符不能在声明文件中使用, 在重载时或在任何其他环境上下文中(例如在声明中) 类)。
方法装饰器的表达式将作为函数调用 在运行时,具有以下三个参数:
- 或者是静态成员的类的构造函数,或者
- 实例成员的类的原型。成员的名称。
- 成员的属性描述符。
然后您可以像此typescript Playground example
一样进行一些丑陋的修改为方便起见,我也在此处提供代码。如果您检查打字稿游乐场或编译此代码,那么要做的一件好事就是查看生成的Javascript,该Javascript清楚地表明这不是为直接函数编写的。
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
function noisy() {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
alert(`I am decorating ${ propertyKey }`);
};
}
class Test {
@noisy()
public testMethod() {
}
}
class DynamicTest {
}
const testInstance = new Test();
testInstance.testMethod();
let dynamics = ["do", "something"];
for (let dynFunction of dynamics) {
DynamicTest.prototype[dynFunction] = new Function(`alert("I am Dynamic ${dynFunction}")`);
let decorator = noisy();
decorator(DynamicTest.prototype, dynFunction, null);
}
const dynamicTestInstance = new DynamicTest();
dynamicTestInstance["do"]();
dynamicTestInstance["something"]();
在不知道您的特定问题的情况下,我无法想到需要以这种方式生成函数。也许是外部逻辑数据流,例如规则引擎?无论如何,这种动态生成很难进行测试和维护,因此请牢记这一点并考虑其他方法。