function MyMethodDecorator(str: string) {
return (targetClassPrototype: any, methodName: string, methodDescr: PropertyDescriptor) => {
// 运行时设置拦截器 做一些操作
const _methodDescr = methodDescr.value;
methodDescr.value = function (...args: any[]) {
console.log('我是methodDescr执行前运行的');
_methodDescr.call(this, ...args);
console.log('我是methodDescr执行后运行的');
};
};
}
class RoleService {
public roleName: string = 'admin';
constructor() {}
@MyMethodDecorator('run decorator method')
DistribRoles(...args: any[]) {
// 分配角色
console.log(this, '分配角色... 参数是', ...args);
}
}
const instance = new RoleService();
instance.DistribRoles(1, 2, 3);
修改属性的描述符必须得通过 Object.defineProperty 方法进行重新才能修改成功,像上头代码中,我们发现直接操作描述符的引用值进行属性的修改成功了,其实并非真正的成功,因为我们上头也说了,改值只有一种方法,为什么在这可以直接以对象的形式操作一个属性描述符呢,是因为底层源码的实现让我们能够通过这种方式进行修改,可以参见下方转义后的es5代码。ps:转义后的代码最终还是通过 Object.defineProperty 这种方式重写了对应的描述符数据。
二次补充,看到下一节中,老师对直接value不生效的原因的解释,加上自己的思考,上头的总结应该是不正确的,改动value不生效,对value重新赋值后,就和以前的没关系了,等于新创建了一个内存地址赋值给了value,要想真正的修改value必须操作的是value的原始地址的引用。