author: 专注前端开发分享JavaScript干货title: JavaScript进阶⑤装饰器与元属性未来JavaScript特性update: 2026-04-28tags: JavaScript,装饰器,元属性,Stage3,类装饰器,方法装饰器,前端进阶作者专注前端开发分享JavaScript干货更新时间2026年4月适合人群掌握ES6想了解前沿JS特性的开发者前言装饰器是什么装饰器Decorator是一种特殊类型的声明可以附加到类、方法、访问器、属性或参数上用于修改其行为。装饰器目前处于Stage 3阶段接近正式标准但 TypeScript 和许多框架如 Angular、NestJS已经在广泛使用。一、装饰器基础当前Stage 3提案1.1 类装饰器// 类装饰器接收类本身functionlogged(constructor){console.log(类${constructor.name}被定义);// 可以返回一个新的类替换原类returnclassextendsconstructor{createdAtnewDate();};}classUser{constructor(name){this.namename;}}// 手动应用装饰器模拟constDecoratedUserlogged(User);constusernewDecoratedUser(张三);console.log(user.createdAt);// 当前时间1.2 方法装饰器// 方法装饰器接收目标原型、方法名、属性描述符functionlog(target,propertyKey,descriptor){constoriginalMethoddescriptor.value;descriptor.valuefunction(...args){console.log(调用方法${propertyKey}参数,args);constresultoriginalMethod.apply(this,args);console.log(方法${propertyKey}返回,result);returnresult;};returndescriptor;}1.3 手动应用装饰器classCalculator{add(a,b){returnab;}}// 手动应用装饰器constdescObject.getOwnPropertyDescriptor(Calculator.prototype,add);log(Calculator.prototype,add,desc);Object.defineProperty(Calculator.prototype,add,desc);constcalcnewCalculator();calc.add(1,2);// 打印日志返回 3二、属性装饰器// 属性装饰器functionrequired(target,propertyKey){console.log(${propertyKey}是必填字段);}// 参数装饰器functionminLength(target,methodName,parameterIndex){console.log(参数${parameterIndex}长度至少 3);}classUser{required name;greet(minLength message){console.log(message);}}三、元属性new.target// new.target指向被 new 调用的构造函数functionPerson(name){if(!new.target){thrownewError(必须使用 new 调用 Person);}this.namename;}constp1newPerson(张三);// ✅constp2Person(李四);// ❌ 报错// 在类中使用classAnimal{constructor(name){if(new.targetAnimal){thrownewError(Animal 是抽象类不能直接实例化);}this.namename;}}classDogextendsAnimal{constructor(name,breed){super(name);this.breedbreed;}}constdognewDog(旺财,金毛);// ✅四、实战用装饰器实现重试机制// 装饰器方法调用失败时自动重试functionretry(times3,delay1000){returnfunction(target,propertyKey,descriptor){constoriginalMethoddescriptor.value;descriptor.valueasyncfunction(...args){letlastError;for(leti0;itimes;i){try{returnawaitoriginalMethod.apply(this,args);}catch(error){lastErrorerror;console.log(第${i1}次失败${delay}ms 后重试...);awaitnewPromise(resolvesetTimeout(resolve,delay));}}throwlastError;};returndescriptor;};}// 模拟不稳定的网络请求classApiService{retry(3,500)asyncfetchData(){if(Math.random()0.7){return{data:成功};}thrownewError(网络错误);}}// 手动应用版本classApiServiceManual{asyncfetchData(){if(Math.random()0.7){return{data:成功};}thrownewError(网络错误);}}constdesc2Object.getOwnPropertyDescriptor(ApiServiceManual.prototype,fetchData);retry(3,500)(ApiServiceManual.prototype,fetchData,desc2);Object.defineProperty(ApiServiceManual.prototype,fetchData,desc2);五、实战用装饰器实现性能测量// 装饰器测量方法执行时间functionmeasure(target,propertyKey,descriptor){constoriginalMethoddescriptor.value;descriptor.valuefunction(...args){conststartperformance.now();constresultoriginalMethod.apply(this,args);constendperformance.now();console.log(方法${propertyKey}执行时间${(end-start).toFixed(2)}ms);returnresult;};returndescriptor;}classDataProcessor{measureprocess(data){conststartDate.now();while(Date.now()-start100){}returndata.map(xx*2);}}// 手动应用版本classDataProcessorManual{process(data){conststartDate.now();while(Date.now()-start100){}returndata.map(xx*2);}}constdesc3Object.getOwnPropertyDescriptor(DataProcessorManual.prototype,process);measure(DataProcessorManual.prototype,process,desc3);Object.defineProperty(DataProcessorManual.prototype,process,desc3);constprocessornewDataProcessorManual();processor.process([1,2,3]);// 打印执行时间六、知识卡概念说明装饰器修改类/方法行为的声明类装饰器接收构造函数方法装饰器接收原型、方法名、描述符属性装饰器接收目标和属性名new.target指向被 new 调用的构造函数Stage 3接近正式标准TypeScript已支持装饰器实验性七、课后作业实现一个readonly装饰器让方法不能被修改实现一个deprecated装饰器调用方法时打印警告用new.target实现一个抽象基类不能直接实例化有问题欢迎评论区留言大家一起讨论标签JavaScript | 装饰器 | 元属性 | Stage3 | 类装饰器 | 方法装饰器 | 前端进阶