Decorators 2๏ธโฃ
Decorator the synthetic sugar
ํด๋์ค ๋ฐ์ฝ๋ ์ดํฐ๋ constructor
๋ฅผ ๋ฐํํ๋ฉด์ ๊ธฐ์กด constructor
๋ฅผ ํ์ฅํ ์ ์๋ค.
constructor
๋ฅผ ํ์ฅํ ๋ super();
๋ ๊ธฐ์กด ํด๋์ค ํ์ฅ์์์ ๋ง์ฐฌ๊ฐ์ง๋ก ๊ธฐ์กด ํด๋์ค์ ์ ๋ณด๋ฅผ ๊ธฐ์ตํ๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ฉด ๋๋ค.
function ClassDeco() {
return function<T extneds {new(...args: any[]): {name: string}}>(target: T) {
return class extends target {
constructor(..._: any[]) {
super(); // not necessary
/* write your code */
}
}
}
}
@ClassDeco
class Person {
name = 'Shou';
get name() {
return this.name;
}
constructor() {
console.log('Creating person object...');
}
getName(intro: string) {
console.log(intro, this.name);
}
}
๋ฐ์ฝ๋ ์ดํฐ๋ ํด๋์ค๋ฅผ ์ ์ํ ๋ ์คํ๋์ง๋ง,
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ํตํด ํด๋์ค๋ฅผ ํ์ฅํ๊ฒ ๋๋ฉด ํ์ฅ๋ ํด๋์ค๋ ์๋ก์ด ์ธ์คํด์ค๋ฅผ ๋ง๋ค์์ ๋ ์๋ํ๋ค.
์ก์ธ์ ๋ฐ์ฝ๋ ์ดํฐ, ๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ๋ descriptor
๋ฅผ ๋ฐํํ๋ฉด์ descriptor
์ ์์ฑ์ ์กฐ์ ํ ์ ์๋ค.
function AccessorDeco(
target: any,
propertyKey: string | Symbol,
descriptor: PropertyDescriptor
): ProretyDescriptor {
return {configurable: false};
}
function MethodDeco(
target: any,
propertyKey: string | Symbol,
descriptor: PropertyDescriptor
): PropertyDescriptor {
return {enumerable: true};
}
class Person {
name = 'Shou';
@AccessorDeco
get name() {
return this.name;
}
constructor() {
console.log('Creating person object...');
}
@MethodDeco
getName(intro: string) {
console.log(intro, this.name);
}
}
Autobind decorator
๋ฉ์๋ ๋ฐ์ฝ๋ ์ดํฐ ์์
class Printer {
message = 'This works!';
showMessage() {
console.log(this.message);
}
}
const printer = new Printer();
const button = document.querySelector('button');
button.addEventListener('click', printer.showMessage);
// undefined
์ ์ฝ๋์์ ๋ฒํผ์ ํด๋ฆญํ์ ๋, This works!
๊ฐ ์๋๋ผ undefined
๊ฐ ์ถ๋ ฅ๋๋ค.
ํด๋ฆญ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ฌ์ฉํ ๋ ์ง์ ํ ํจ์๊ฐ ์คํ๋๋๋ฐ,
๊ทธ ํจ์ ์์ ์๋ this
๊ฐ printer.showMessage()
๋ฅผ ์ง์ ํธ์ถํ์ ๋์ this
์ ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค.
printer.showMessage()
์์์this
๋Printer
ํด๋์ค๋ฅผ ์ฐธ์กฐํ์ง๋งbutton.addEventListner('click', printer.showMessage)
์์์this
๋ ์ด๋ฒคํธ ๋์์ธ ๋ฒํผ์ ์ฐธ์กฐํ๋ค.addEventListener
๊ฐthis
๋ฅผ ์ด๋ฒคํธ์ ๋์๊ณผ ๋ฐ์ธ๋ฉํ๊ธฐ ๋๋ฌธ์!
button.addEventListener('click', printer.showMessage.bind(printer));
// This works!
์ด ๊ฒฝ์ฐ ์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์์ ํ๋ฉด This works!
๊ฐ ์ถ๋ ฅ๋์ง๋ง ์ด๋ฅผ ๋ฐ์ฝ๋ ์ดํฐ๋ฅผ ์ด์ฉํด this
๊ฐ ์๋์ผ๋ก ๋ฐ์ธ๋ฉ๋๊ฒ ๋ง๋ค ์ ์๋ค.
function Autobind(
_: any,
_2: string,
descriptor: PropertyDescriptor
) {
const original = descriptor.value;
const adjusted: PropertyDescriptor = {
configurable: true,
enumerable: false,
/* ์ฌ์ฉ์๊ฐ ์ด ํ๋กํผํฐ์ ์ ๊ทผ ์๋ํ ๋ ํ๋กํผํฐ์ ๊ฐ์ด๋ ํจ์๊ฐ ์ง์ ์คํ๋์ง ์๊ฒ ํ๊ธฐ ์ํจ */
get() {
const bound = original.bind(this);
return bound;
}
};
return adjusted;
}
class Printer {
message = 'This works!';
@Autobind
showMessage() {
console.log(this.message);
}
}
const button = document.querySelector('button');
button.addEventListener('click', printer.showMessage);
// This works!
getter
๋ ์คํ๋๊ณ ์๋ ํจ์, ๊ทธ๊ฒ์ด ์ํ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๊ธฐ ๋๋ฌธ์
getter
์์ bind
ํ this
๋ ์๋ ์ ์ํ ๋ฉ์๋์ ์๋ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ๋ค.
๊ทธ๋ฌ๋ฏ๋ก Autobind
๋ฐ์ฝ๋ ์ดํฐ๋ฅผ showMessage
๋ฉ์๋์ ์ฅ์ํ๋ฉด
์ด๋ฒคํธ ๋ฆฌ์ค๋์์ bind
๋ฅผ ์ง์ ํ์ง ์์๋ ์๋์ผ๋ก Printer
ํด๋์ค์ message
๋ฅผ bind
ํ๋ค!
'๐ Study > TypeScript' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[TS] Project Drag & Drop 1๏ธโฃ (2) | 2023.03.27 |
---|---|
[TS] Decorators 3๏ธโฃ (0) | 2023.03.24 |
[TS] Decorators 1๏ธโฃ (1) | 2023.03.20 |
[TS] Generics 2๏ธโฃ (0) | 2023.03.17 |
[TS] Generics 1๏ธโฃ (4) | 2023.03.16 |