理解TS装饰器Decorator

理解TS装饰器Decorator

介绍

详细的关于ts中装饰器的使用和语法可以参考 ts官网中decorator这一章节,或者阮一峰的ts教程的decorator章节这里这是个人对装饰器的理解和使用。

装饰器是一种特殊类型的声明,使用 @expression 这种形式,其中 expression 求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息作为参数传入。

装饰器是一种类 class 相关的语法,所以只能用在 class 里面,个人理解装饰器相当于在外层加入了一层拦截作用
下面针对不同装饰器举例说明

类装饰器

类装饰器在类声明之前被声明(紧靠着类声明)。类装饰器应用于类构造函数,可以用来监视,修改或替换类定义
类装饰器表达式会在运行时当做函数被调用,类的构造函数函数作为其唯一的参数

下面看一个类装饰器的例子

// 装饰器
function myDecorator(constructor: Function) {
  Object.defineProperty(constructor.prototype, 'sayName', {
    value: function() {
      return 'myDecorator sayName'
    }
  })
}

@myDecorator
class Person {
  public name: string
  constructor(name: string) {
    this.name = name
  }
  sayName() {
    return this.name
  }
}

const p1 = new Person('yy')
console.log(p1.sayName()) // myDecorator sayName

如果类装饰器返回一个值,它会使用提供的构造函数来替换类的声明

下面是一个构造函数重载的例子,这里的类装饰器就是返回了一个值(返回一个继承后的原构造函数)

// 装饰器
function myDecorator<T extends {new(...args: any[]): {}}>(constructor: T) {
  return class extends constructor {
    name: string = 'new name'
    age: number = 17
    sayName() {
      return this.name + this.age
    }
  }
}

@myDecorator
class Person {
  public name: string
  constructor(name: string) {
    this.name = name
  }
  sayName() {
    return this.name
  }
}

const p1 = new Person('yy')
console.log(p1.sayName()) // new name17
console.log(p1) // {name: 'new name' age: 17}
// 注意,虽然 p1 有 age 属性,但是不能通过 p1.age 来访问

方法装饰器

方法装饰器声明在一个方法的声明之前(紧靠着方法声明)。它会被应用到方法的属性描述符上用来监视,修改或替换方法定义
方法装饰器表达式在运行时当做函数被调用,传入三个参数

  • 对于静态成员来说是类的构造函数,对于实例成员是类的原型对象
  • 成员的名字
  • 成员的属性描述符

如果方法装饰器返回一个值,它会被用作方法的属性描述符

// 装饰器
function myDecorator(value: string) {
 return function(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
   console.log(target, propertyKey) // {} sayName
   descriptor.value = function() {
     return 'decorator ' + value
   }
 }
}

class Person {
  public name: string
  constructor(msg: string) {
    this.name = msg
  }
  @myDecorator('hellowee')
  sayName() {
    return this.name
  }
}

const p1 = new Person('yy')
console.log(p1.sayName()) // decorator hellowee

再看一个关于 log 的装饰器,可以起到输出日志的作用

// 装饰器
function log(target: any, prop: string, descriptor: PropertyDescriptor) {
  let oldValue = descriptor.value
  descriptor.value = function() {
    console.log('log--> sum')
    return oldValue.apply(this, arguments)
  }
}

class Math2 {
  @log
  sum(a: number, b: number): number {
    return a + b
  }
}

const math = new Math2()
console.log(math.sum(1, 2))
// log--> sum
// 3
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值