Day 13 Decorator Part - 1

今天要介绍的是 Decorator,会先介绍用法之後再来看看为甚麽要用这个,因为该章节一开始的介绍大约是在说 Decorator 虽然并不会对页面或是使用者有直接的影响,但是它能够帮助我们更好的使用一些 function 或是 class之类的,我还不是很能理解,遂等跟着课程看能理解到多少。

要使用 Decorator 时记得要先去 tsconfig.json 把 experimentalDecorators 打开哦:

"experimentalDecorators": true

使用 Decorator 其实满简单的,其实就是再写一个函式然後用 @ 符号放在要装饰的 class、function、参数、属性上面,然後 Decorator 就会对其产生作用。

function logger(constructor: Function) {
  console.log('Logging...')
  console.log(constructor)
}

@logger
class Person {
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }
}

Decorator 有五种:

  1. Class Decorator
  2. Property Decorator
  3. Method Decorator
  4. Accessor Decorator
  5. Parameter Decorator

上面的 @logger 范例就是 Class Decorator,被装饰的就是 class 里面的 constructor function,透过 Class Decorator 可以另外再对 constructor 做事情但不用更动原本的程序码。

Property Decorator 顾名思义是装饰属性的,写法如下:

function propertyDecorator(target: any, propertyKey: string) {
  console.log(target)
  console.log(propertyKey)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }
}

target 为被装饰 class 的 constructor,propertyKey 为被装饰的属性,这边是 name

Method Decorator 是对 function 做装饰,写法如下:

function methodDecorator(target: any, name: string, descriptor: PropertyDescriptor) {
  console.log('Method decorator')
  console.log('target:', target)
  console.log('name:', name)
  console.log('descriptor:', descriptor)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }

  @methodDecorator
  getPersonName() {
    return this.name
  }
}

https://ithelp.ithome.com.tw/upload/images/20210928/201319890lQDKjR7p7.png
target 为被装饰 class 的 constructor,name 为被装饰的方法名称,descriptor 为描述该物件会有的一些属性跟值(MDN说明)。

Accessor Decorator 的写法跟 Method decorator 一样,他们唯一不同的地方在於 descriptor 的内容勿不相同,有别於上面的 configurableenumerablevaluewritable,Accessor Decorator 的 descriptor 里面分别是 configurableenumerablesetget。两者的差别在於可以使用的 descriptor 方法不同,如果是用 Method decorator 就能够使用 descriptor.value 或是 descriptor.writable,如果是用 Accessor Decorator 就能够使用 descriptor.set 或是 descriptor.get

最後一个 Parameter Decorator 相信看到这边已经知道它是要装饰什麽了吧!

function parameterDecorator(target: any, propertyKey: string, propertyIndex: number) {
  console.log('target:', target)
  console.log('propertyKey:', propertyKey)
  console.log('propertyIndex:', propertyKey)
}

class Person1 {
  @propertyDecorator
  name = 'Claire'

  constructor() {
    console.log('Create person object...')
  }

  foo(@parameterDecorator arg: string) {
    if (typeof arg === "string") {
      console.log(arg.toUpperCase());
    }
  }

  @methodDecorator
  getPersonName() {
    return this.name
  }
}

https://ithelp.ithome.com.tw/upload/images/20210928/20131989xbnROIjFQB.png
target 为被装饰 class 的 constructor,propertyKey 是要被装饰的参数的函式名称,propertyIndex 是参数的 index(从 0 开始)。

今天先简单介绍一下各种 Decorator 的写法,谢谢阅读。:)


<<:  Day 13 MSW的return Error Type

>>:  [Day 15 - 小试身手] 用HTML、CSS、JS打造个人网站 (2)

Day 17 - SwiftUI开发学习1(按钮)

我们统整一下前16天的内容,我们花了很多的时间学习swift语言的基本,学完语言之後我们要开始进入到...

企划实现(30)

止损 止损顾名思义就是停止损失,今天在做企划的同时,世界并不会停下来等你发展,所以如果在做企划的同时...

Day6-我通知你的通知通知我!!!(无误!

标题那个还真的是没有写错~ 且听我细细道来~ ------------------------ 【一...

03 | 认识 WordPress「区块编辑器」的发展和简介

关於 Block Editor(区块编辑器)的各类延伸有很多,我们这篇文章尽量保持简单,但您可以从...

第九天:建立练习专案

接下来我们建立後续章节要使用的练习专案,我预想了一个「购物车及运费计算机」做为情境,整个流程会示范如...