浅谈Typescript 装饰器执行顺序

 更新时间:2026年06月16日 09:37:39   作者:起这个名字  
TypeScript中装饰器的执行顺序遵循一套固定的规则,可以从同一声明上的多个装饰器和类中不同成员的装饰器两个维度来理解,下面就来详细的介绍一下装饰器执行顺序,感兴趣的可以了解一下

TypeScript 中装饰器的执行顺序遵循一套固定的规则,可以从同一声明上的多个装饰器类中不同成员的装饰器两个维度来理解。

1. 同一声明上多个装饰器的顺序

当一个声明(如类、方法、属性)上应用了多个装饰器时:

  • 装饰器表达式(工厂函数)的求值顺序:从上到下
  • 装饰器函数(返回的函数本身)的执行顺序:从下到上
function first() {
  console.log('first(): 工厂求值');
  return function (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
    console.log('first(): 装饰器执行');
  };
}

function second() {
  console.log('second(): 工厂求值');
  return function (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
    console.log('second(): 装饰器执行');
  };
}

class Example {
  @first()
  @second()
  method() {}
}

输出顺序:

first(): 工厂求值
second(): 工厂求值
second(): 装饰器执行
first(): 装饰器执行

2. 类中不同成员装饰器的整体顺序

对于类中的不同成员(属性、方法、参数等),装饰器的执行顺序由成员类型和所属(实例/静态)决定,与源代码书写顺序无关。

整体求值顺序如下:

  1. 实例成员:先参数装饰器,再方法/访问器/属性装饰器。
    对于每个实例成员,按照它们在类中出现的从上到下顺序处理。
  2. 静态成员:同样先参数装饰器,再方法/访问器/属性装饰器。
    对于每个静态成员,按照它们在类中出现的从上到下顺序处理。
  3. 构造函数参数装饰器
  4. 类装饰器(最后执行)。

可以浓缩成一句话:实例 → 静态 → 构造参数 → 类,每一组内部按成员的源代码顺序,且每个成员内是参数装饰器优先于该成员的属性/方法/访问器装饰器。

3. 示例演示

function classDecorator() {
  console.log('类装饰器工厂');
  return function (constructor: Function) {
    console.log('类装饰器执行');
  };
}

function propertyDecorator(name: string) {
  console.log(`属性装饰器工厂: ${name}`);
  return function (target: any, propertyKey: string) {
    console.log(`属性装饰器执行: ${name}`);
  };
}

function methodDecorator(name: string) {
  console.log(`方法装饰器工厂: ${name}`);
  return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    console.log(`方法装饰器执行: ${name}`);
  };
}

function parameterDecorator(name: string) {
  console.log(`参数装饰器工厂: ${name}`);
  return function (target: any, propertyKey: string, parameterIndex: number) {
    console.log(`参数装饰器执行: ${name}`);
  };
}

@classDecorator()
class Demo {
  @propertyDecorator('实例属性')
  instanceProp: string;

  @propertyDecorator('静态属性')
  static staticProp: string;

  constructor(@parameterDecorator('构造参数') param: string) {
    this.instanceProp = param;
  }

  @methodDecorator('实例方法')
  instanceMethod(@parameterDecorator('实例方法参数') arg: number) {}

  @methodDecorator('静态方法')
  static staticMethod(@parameterDecorator('静态方法参数') arg: number) {}
}

运行这段代码,控制台输出顺序如下:

属性装饰器工厂: 实例属性
属性装饰器执行: 实例属性          // 实例属性,无参数装饰器
方法装饰器工厂: 实例方法
参数装饰器工厂: 实例方法参数
参数装饰器执行: 实例方法参数      // 实例方法参数优先
方法装饰器执行: 实例方法          // 实例方法在后

属性装饰器工厂: 静态属性
属性装饰器执行: 静态属性          // 静态属性
方法装饰器工厂: 静态方法
参数装饰器工厂: 静态方法参数
参数装饰器执行: 静态方法参数      // 静态方法参数优先
方法装饰器执行: 静态方法          // 静态方法在后

参数装饰器工厂: 构造参数
参数装饰器执行: 构造参数          // 构造函数参数

类装饰器工厂
类装饰器执行                      // 类装饰器最后

4. 总结要点

  • 同一成员多装饰器:工厂自上而下求值,装饰器自下而上执行。
  • 多成员:先处理实例成员(从上到下),再处理静态成员(从上到下),然后构造函数参数,最后类装饰器。

到此这篇关于浅谈Typescript 装饰器执行顺序的文章就介绍到这了,更多相关Typescript 装饰器执行顺序内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 论Bootstrap3和Foundation5网格系统的异同

    论Bootstrap3和Foundation5网格系统的异同

    这篇文章主要介绍了Bootstrap3和Foundation5网格系统,网格的基本构造,如何构建的,描述它们的主要部件,以及它们对不同屏幕的大小表现出的差异,感兴趣的小伙伴们可以参考一下
    2016-05-05
  • js同比例缩放图片的小例子

    js同比例缩放图片的小例子

    这篇文章介绍了js同比例缩放图片的小例子,有需要的朋友可以参考一下
    2013-10-10
  • Safari 中 filter: blur() 高斯模糊引发的性能问题及解决方案(推荐)

    Safari 中 filter: blur() 高斯模糊引发的性能问题及解决方案

    在Safari浏览器中使用CSS滤镜如filter:blur()时,可能会遇到性能问题,如页面卡顿和小方块现象,这些问题通常与渲染机制和硬件加速的缺失有关,通过开启硬件加速,如使用transform:translate3d(0,0,0),可以有效解决这些问题,并提升用户体验
    2024-10-10
  • JavaScript闭包原理与使用介绍

    JavaScript闭包原理与使用介绍

    闭包是js的一个难点也是它的一个特色,是我们必须掌握的js高级特性,下面这篇文章主要给大家介绍了关于JavaScript闭包函数的相关资料,需要的朋友可以参考下
    2022-10-10
  • js实现简单的手风琴效果

    js实现简单的手风琴效果

    本文主要介绍了js实现简单手风琴效果的实例,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • js中Array.forEach跳出循环的方法实例

    js中Array.forEach跳出循环的方法实例

    相信大家都知道forEach适用于只是进行集合或数组遍历,for则在较复杂的循环中效率更高,下面这篇文章主要给大家介绍了关于js中Array.forEach跳出循环的相关资料,需要的朋友可以参考下
    2021-09-09
  • ReactHooks+ts(函数组件)实现原生轮播的示例

    ReactHooks+ts(函数组件)实现原生轮播的示例

    这篇文章主要介绍了ReactHooks+ts函数组件实现原生轮播,在这里下载依赖第一个是js依赖第二个是ts依赖,通过实例代码介绍了创建tsx文件的方法,需要的朋友可以参考下
    2022-05-05
  • 小程序清理本地缓存的方法

    小程序清理本地缓存的方法

    这篇文章主要介绍了小程序清理本地缓存的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-08-08
  • 原生js+css实现tab切换功能

    原生js+css实现tab切换功能

    这篇文章主要为大家详细介绍了原生js+css实现tab切换功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-09-09
  • JavaScript 读取元素的CSS信息的代码

    JavaScript 读取元素的CSS信息的代码

    在前端开发的工作中,总是会涉及到一些JavaScript和CSS信息交互的内容。
    2010-02-02

最新评论