[TS] Chapter 8. Decorators_1

변진상·2023년 6월 7일
0

Typescript 학습

목록 보기
13/13

목표: Decorators에 대해 학습한다.

들어가기 전

데코레이터란?

데코레이터는 클래스, 속성, 메서드, 접근 제어자, 매개변수 등에 사용할 수 있는 특별한 함수이다. 데코레이터는 메타 프로그래밍 하는데 유용하게 사용될 수 있다. 클래스에 사용되는 데코레이터 함수의 인자로 주어지는 값은 class의 구현부 전체이다.

데코레이터 활성화를 위한 tsconfig.json파일 수정

"experimentalDecorators": true,                   
/* Enable experimental support for legacy experimental decorators. */

클래스 데코레이터 만들기

function Logger(constructor: Function) {
  console.log("Logger!");
}

@Logger
class Person {
  name = "otter";

  constructor() {
    console.log("Creating Person object...");
  }
}

// const ott = new Person();
  • 데코레이터 함수를 하나 만들어 패러미터를 class의 생성자 함수로 정한다.
  • 데코레이터는 클래스의 인스턴스가 생성되지 않아도 class 선언만으로도 실행이 된다.
  • 문법은 @를 붙여준다.

데코레이터 팩토리 함수

데코레이터 팩토리 함수란 데고레이터 함수를 감싸는 래퍼 함수이다. 데코레이터 팩토리 함수는 인자를 받을 수 있고 반환 값을 익명함수로 하여 데코레이터 함수를 반환한다.
데코레이터 팩토리 함수를 이용하면, 인자를 전달해 줄 수 있어 데코레이션 함수의 기능을 더 풍부하게 할 수 있다.

function Logger(c: string) { // 데코레이터 팩토리 함수의 parameter가 주어진다.
  // console.log("Logger!");

  return function (constructor: Function) {
    console.log("Logger!");
    console.log(constructor); // 테코레이터 함수의 인자
    console.log(c); // 데코레이터 팩토리 함수에서 전달되는 인자
  };
}

@Logger("test~~")
class Person {
  name = "otter";

  constructor() {
    console.log("Creating Person object...");
  }
}

// const ott = new Person();

데코레이터 팩토리 함수 응용

function WithTemplate(template: string, hookId: string) {
  return function (constructor: any) {
    const hookEl = document.getElementById(hookId); // 두번째 인자로 주어진 HTML El의 ID로 DOM에 접근
    const p = new constructor();
    if (hookEl) {
      hookEl.innerHTML = template; // 첫번째 인자로 주어진 템플릿을 두번째 인자로 주어진 HTML El안에 삽입
      hookEl.querySelector("h1")!.textContent = p.name;
    }
  };
}

@WithTemplate("<h1>My Person Object</h1>", "app")
class Person {
  name = "Max";

  constructor() {
    console.log("Creating person object...");
  }
}

const pers = new Person();

console.log(pers);

데코레이터 실행 순서

  • 먼저 Factory들을 위에서 아래의 순서로 먼저 실행(중간에 Decorator가 끼어있으면 skip)
  • 후에 역방향으로 Decorator들을 실행

만약 다음과 같이 클래스 데코레이터 함수를 반환하는 데코레이터 팩토리가 사용되고 있다고 생각해보자.

@DecoratorFactory1
@Decorator2
@DecoratorFactory3
Class ClassName {
...
}

이럴 경우 실행 순서는 아래와 같다.

  1. @DecoratorFactory1
  2. @DecoratorFactory3
  3. @DecoratorFactory3가 반환하는 Decorator3
  4. Decorator2
  5. @DecoratorFactory1가 반환하는 Decorator1
@Decorator1("1") // Factory
@Decorator3
@Decorator2("2") // Factory
class SomeClass {
  constructor() {
    console.log("creating object");
  }
}

profile
자신을 개발하는 개발자!

0개의 댓글