Chr*_*ris 4 javascript decorator typescript
我想将装饰器函数应用于类中的所有方法,以便可以替换:
class User {
@log
delete() {}
@log
create() {}
@log
update() {}
}
Run Code Online (Sandbox Code Playgroud)
与
@log
class User {
delete() {}
create() {}
update() {}
}
Run Code Online (Sandbox Code Playgroud)
Pap*_*och 12
对于将来偶然发现这一点的人:
我从大卫的回答中获得灵感并创建了我自己的版本。后来我把它做成了一个npm包: https: //www.npmjs.com/package/decorate-all
在OP的场景中,会这样使用
@DecorateAll(log)
class User {
delete() {}
create() {}
update() {}
}
Run Code Online (Sandbox Code Playgroud)
创建一个类装饰器,并枚举目标原型上的属性。
对于每个属性:
修改属性描述符很重要,因为您要确保装饰器可以与其他修改属性描述符的装饰器一起正常工作。
function log(target: Function) {
for (const propertyName of Object.keys(target.prototype)) {
const descriptor = Object.getOwnPropertyDescriptor(target.prototype, propertyName);
const isMethod = descriptor.value instanceof Function;
if (!isMethod)
continue;
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
const result = originalMethod.apply(this, args);
console.log("The return value is: " + result);
return result;
};
Object.defineProperty(target.prototype, propertyName, descriptor);
}
}
Run Code Online (Sandbox Code Playgroud)
基类方法
如果您希望这也影响基类方法,则可能需要遵循以下几条原则:
function log(target: Function) {
for (const propertyName in target.prototype) {
const propertyValue = target.prototype[propertyName];
const isMethod = propertyValue instanceof Function;
if (!isMethod)
continue;
const descriptor = getMethodDescriptor(propertyName);
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log("The method args are: " + JSON.stringify(args));
const result = originalMethod.apply(this, args);
console.log("The return value is: " + result);
return result;
};
Object.defineProperty(target.prototype, propertyName, descriptor);
}
function getMethodDescriptor(propertyName: string): TypedPropertyDescriptor<any> {
if (target.prototype.hasOwnProperty(propertyName))
return Object.getOwnPropertyDescriptor(target.prototype, propertyName);
// create a new property descriptor for the base class' method
return {
configurable: true,
enumerable: true,
writable: true,
value: target.prototype[propertyName]
};
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1165 次 |
| 最近记录: |