ECMAScript 7 に提案されている機能に Decorators があります。クラスやメソッドにアノテーションや修正を加える機能です。 Babel や TypeScript で実装されていたので試してみました。

必要な知識

  • npm コマンド
  • babel コマンド
  • tsc コマンド
  • ECMAScript 5
  • ECMAScript 6
  • TypeScript

インストール

Babel と TypeScript をインストールします。 Decorators が実装されるのは TypeScript 1.5.0 からでまだ安定版には入っていないのでバージョンの指定が必要です。

$ npm install -g babel
$ npm install -g typescript@1.5.0-alpha

メソッドをデコレートする

クラスのメソッドの定義の前に @decorator と書くとそのメソッドの情報が decorator に渡されます。具体的にはクラスの prototype 、メソッドの名前、メソッドのディスクリプタが、この順に渡されます。ディスクリプタは Object.createObject.defineProperty に渡すオブジェクトと同じものです。それをいじることでここでは引数に 1 を加えています。

それらのオブジェクトを編集することでメソッドの動作や enumerable なんかの情報を変更することができます。

簡単な例を作ってみます。

function bind_1(target, name, descriptor) {
    var fn = descriptor.value;
    descriptor.value = function(...args) {
        return fn.call(this, 1, ...args);
    };
}

class A {
    @bind_1
    sum(...args) {
        return args.reduce((a, b) => a + b, 0);
    }
}

console.log(new A().sum(10)); // 11

bind_1 がデコレータです。 @bind_1 と指定することで sum メソッドをデコレートしています。 descriptorvalue を書き換えることでメソッドを差し替えています。

Babel

これを babel コマンドで変換します。 --stage 1 を指定しないと Decorators は有効にならないので忘れず指定します。

$ babel --stage 1 --out-file out.js src.js

TypeScript

同じプログラムを TypeScript としてコンパイルできます。拡張子を .ts に変えておきます。 ECMAScript 5 じゃないとコンパイルできないのでオプションを指定します。

$ tsc --target ES5 --out out.js src.ts

まとめ

  • ECMAScript 7 に Decorators が提案されている
  • クラス・メソッド・引数などの動作や性質を変更できる
  • Babel / TypeScript ですでに実装が始まっている