Typescript 공부하기 8일차 (2022.10.02)
1. 데코레이터
1) 특징
- 함수를 감싸는 함수
- GoF에 소개된 구조적 디자인 패턴 중 하나로서, 기존 함수를 바꾸지 않고 함수를 관찰, 수정, 재정의(오버라이딩)할 수 있는 함수.
- 가독성 개선
- 반복되는 코드 줄이기
- 단일책임원칙
ㄴ 단일책임원칙(SRP, Single Responsibility Principle)
객체지향 5대 원칙인 SOLID 원칙 중 하나로, 프로그램에서 모든 모듈, 클래스, 함수는 한 번에 하나의 역할 만 책임져야 한다는 원칙, 즉, 한 번에 한 가지 일만 해야 한다.
2) 주의사항
- 표준화되지 않은 기능
ㄴ 데코레이터는 앵귤러 프레임워크를 지원하기 위해 추가된 것으로 아직 표준화되지 않은 기능.
ㄴ 즉, 사용중인 데코레이터가 비표준화되거나 호환성이 깨질 가능성이 있다.
3) 데코레이터에 사용되는 JS개념
- 고차함수: 함수를 반환하는 함수
- 설명자: 함수의 메타데이터
- 클로저: 외부함수의 매개변수에 접근
- 일급 객체: 함수의 변수 할당
ㄴ JS의 function은 일급객체
ㄴ First Class Citizen, First Class Object: 객체로서 사용되는 데 제약이 없는 상태.
ㄴ 즉, 일반적으로 객체가 사용될 수 있는 곳에는 함수도 쓰일 수 있다.
3-1) 일급객체의 특징
- 모든 일급 객체는 함수의 실질적인 매개변수가 될 수 있다.
- 모든 일급 객체는 함수의 반환 값이 될 수 있다.
- 모든 일급 객체는 할당의 대상이 될 수 있다.
- 모든 일급 객체는 비교 연산(==, equal)을 적용할 수 있다.
3-2) 클로저의 특징
- 외부 함수의 실행이 끝나도 내부함수에서 외부함수의 context에 접근할 수 있는 것
- context의 정보는 가비지 컬렉터(쓰레기 수집가)에 의해 메모리에서 삭제되어야하지만,
- 가비지 컬렉터는 값을 참조하는 곳이 한 곳이라도 있다면 그 값을 제거하지 않는다.
- 즉, 외부 함수가 반환한 내부 함수에서 파라미터를 참조하구 있기 때문에 가비지 컬렉터가 context의 정보를 삭제하지 않는다.
3-3) 고차 함수의 특징
- 함수를 반환하는 함수
- 함수를 파라미터로 반환하기도 한다.
- 클래스 메서드는 고차 함수의 파라미터로서 정달했을 때, 메서드는 인스턴스에 대한 this 바인딩을 잃어버린다.
- 따라서 higher order 함수를 호출할 때 인스턴스와 메서드를 함께 인자로 전달해줘야 한다.
- 이런한 불편함 때문에 다른 언어에서 존재하는 데코레이션 문법이 JS사용자에게 제안되었다.
- 데코레이터 팩토리를 이해하기 위해서도 고차 함수를 알아야함
3-4) 설명자(Property Descriptor)
- configurable: 기본값은 true. property의 property descriptor가 수정 가능 여부
ex) writable, enumerable, configurabledml tnwjd rksmd duqn
- enumerable: 기본값은 true. 열거 가능 여부
ex) Object.keys로 열거 가능 여부
- value: 객체의 프로퍼티 값
ex) method에서 property descriptor의 value는 method
- writable: 기본값은 true. 프로퍼티의 수정 가능 여부
- get: 객체에 접근할 때 실행될 함수
- set: 객체를 수정할 때 실행될 함수
2. Decorator Factory
- 고차함수 = 함수를 반환하는 함수
- 팩토리 = 어떤 인스턴스를 생성하여 반환하는 함수, 메서드
- 데코레이터 팩토리 = 데코레이터 함수를 반환하는 함수
- 데코레이터 함수는 특정 인자만 받는다.
- 데코레이터에 추가적인 인자를 줄 때는 고차함수에 매개변수를 추가하여 데코레이터 함수 내부에서 사용 할 수 있다.
3. Class Decorator
- 생성자 함수를 관찰, 수정, 오버라이딩(재정의)
- 기존 클래스의 코드를 변경하지 않고 property를 추가하거나, 생성자 함수에서 기능을 추가하고 싶을 때 사용
1) 특징
- 클래스 선언 직전에 사용
- 런타임에 함수로서 호출
- 생성자 함수에 적용
- target 매개변수는 생성자 함수
2) 용도
- 값을 반환하지 않는 경우 클래스의 기존 생성자 함수를 그대로 사용
- 데코레이터가 값을 반환하면, 그 반환값으로 생성자 함수를 교체(재정의)
- 기존 생성자 함수에 기능을 확장하고 싶다면 class extends constructor와 같이 생성자 함수를 확장하여 반환
3) 주의사항
- 데코레이터로 class에 property를 추가해도 type system에서는 알지 못함
ㄴ 데코레이터는 런타임에 호출되기 때문
- d.ts 파일(타입 선언 파일), declare class에는 데코레이터 사용 불가
4. Method Decorator
1) 특징
- 매서드를 관찰, 수정, 오버라이딩(재정의) 가능
- 메서드의 Property descriptor를 수정하거나 기존 메서드 앞 뒤로 기능을 추가하고 싶을 때 사용
ㄴ (로깅, 타이머(performance), permission guard, etc.)
2) 용도
- 데코레이터가 값을 반환하면, 그 반환 값으로 propertyDescriptor가 교체됨
- 메서드를 교체하고 싶다면 descriptor.value에 새 함수 할당