wangdoc / typescript-tutorial

TypeScript 教程
https://wangdoc.com/typescript
2.43k stars 256 forks source link

第17章 装饰器 第9节中装饰器的执行顺序的装饰器应用描述问题 #84

Closed luoweihua7 closed 10 months ago

luoweihua7 commented 10 months ago

原文描述是

原型方法的装饰器首先应用,然后是静态属性和静态方法装饰器,接下来是实例属性装饰器,最后是类装饰器。

经过测试,使用 md 中的源码,增加了静态方法装饰器,使用在线的 playground,分别选择 5.0.4 / 5.2.2 运行测试

function d(str:string) {
  console.log(`评估 @d(): ${str}`);
  return (
    value:any, context:any
  ) => console.log(`应用 @d(): ${str}`);
}

function log(str:string) {
  console.log(str);
  return str;
}

@d('类装饰器')
class T {
  @d('静态属性装饰器')
  static staticField = log('静态属性值');

  @d('静态方法装饰器1')
  static fn1(){}

  @d('原型方法装饰器')
  [log('计算方法名')]() {}

  @d('实例属性装饰器')
  instanceField = log('实例属性值');

  @d('静态方法装饰器2')
  static fn2(){}
}

结果输出是

[LOG]: "评估 @d(): 类装饰器" 
[LOG]: "评估 @d(): 静态属性装饰器" 
[LOG]: "评估 @d(): 静态方法装饰器1" 
[LOG]: "评估 @d(): 原型方法装饰器" 
[LOG]: "计算方法名" 
[LOG]: "评估 @d(): 实例属性装饰器" 
[LOG]: "评估 @d(): 静态方法装饰器2" 
[LOG]: "应用 @d(): 静态方法装饰器1" 
[LOG]: "应用 @d(): 静态方法装饰器2" 
[LOG]: "应用 @d(): 原型方法装饰器" 
[LOG]: "应用 @d(): 静态属性装饰器" 
[LOG]: "应用 @d(): 实例属性装饰器" 
[LOG]: "应用 @d(): 类装饰器" 
[LOG]: "静态属性值" 

所以在5.x的版本下,结论应该是

静态方法装饰器首先应用,然后是原型方法的装饰器和静态属性装饰器,接下来是实例属性装饰器,最后是类装饰器。


而使用4.x的版本输出结果为,也与描述不符

[LOG]: "计算方法名" 
[LOG]: "静态属性值" 
[LOG]: "评估 @d(): 原型方法装饰器" 
[LOG]: "应用 @d(): 原型方法装饰器" 
[LOG]: "评估 @d(): 实例属性装饰器" 
[LOG]: "应用 @d(): 实例属性装饰器" 
[LOG]: "评估 @d(): 静态属性装饰器" 
[LOG]: "应用 @d(): 静态属性装饰器" 
[LOG]: "评估 @d(): 静态方法装饰器1" 
[LOG]: "应用 @d(): 静态方法装饰器1" 
[LOG]: "评估 @d(): 静态方法装饰器2" 
[LOG]: "应用 @d(): 静态方法装饰器2" 
[LOG]: "评估 @d(): 类装饰器" 
[LOG]: "应用 @d(): 类装饰器" 
ruanyf commented 10 months ago

谢谢指出,已经更正。