studye / typescript

타입스크립트는 자바스크립트랑 다른 언어인가요?
7 stars 0 forks source link

[Chapter 4] Decorator syntax #18

Open laziel opened 7 years ago

laziel commented 7 years ago

Decorator is simply function

@sealed
class Greeter {
    greeting: string;
    constructor(message: string) {
        this.greeting = message;
    }
    greet() {
        return "Hello, " + this.greeting;
    }
}

function sealed(constructor: Function) {
    Object.seal(constructor);
    Object.seal(constructor.prototype);
}

클래스를 상속(#13 참조)하는 것과 달리, 데코레이터는 정의된 데코레이터 함수를 클래스 생성자, 속성 등에 대하여 실행하는것이다. 참조: https://stackoverflow.com/a/38687651

Multiple decorators

데코레이터는 여러개 지정할 수 있다. 실행 순서는 정의한 순서 반대로 실행된다.

function simpleDecorator(constructor: Function) { console.log('simple called'); }
function secondDecorator(constructor: Function) { console.log('second called'); }

@simpleDecorator
@secondDecorator
class ClassWithSimpleDecorator { ... }

// 실행하면 아래와 같이 출력:
// second called
// simple called

JS로 변환된 결과:

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
function simpleDecorator(constructor) { console.log('simple called'); }
function secondDecorator(constructor) { console.log('second called'); }
var ClassWithSimpleDecorator = (function () {
    function ClassWithSimpleDecorator() {
    }
    return ClassWithSimpleDecorator;
}());
ClassWithSimpleDecorator = __decorate([
    simpleDecorator,
    secondDecorator
], ClassWithSimpleDecorator);

for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) => 데코레이터는 정의한 역순으로 실행되도록 명시되어 있음.

Decorator factory

데코레이터가 파라미터를 받게 하기 위해 팩토리 패턴을 사용한다. 데코레이터 함수를 반환하는 함수.

function decoratorFactory(name: string) { // this is the decorator factory
    return function (target) { // this is the decorator
        // do something with 'target' and 'name'...
    }
}

@decoratorFactory('testName')
class ClassWithDF{ ... }
laziel commented 7 years ago

ES7 Decorators https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841 Compatibility table http://kangax.github.io/compat-table/esnext/

데코레이터 문법은 ES7 스펙에 아직 포함되진 않았지만 제안되어 있는 단계.