请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

针对本节的思考(方法装饰器中的属性描述符)

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的原始地址的引用。

正在回答

1回答

    总结大体对了,细节如下:

  1.  生成新的数据属性  dataprop.

  2. 保存 dataprop.value ,以保留原来的方法

  3. 然后修改 dataprop.value 的指向,指向新的空间,创建了一个内存地址赋值给了value

  4. 然后通过 Object.defineProperty  把修改了value指向 的dataprop  绑定到 原来的方法上

  5. 执行原来方法,就会找到 dataprop.value 的指向的方法来执行

0 回复 有任何疑惑可以回复我~
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信