web-dev-qa-db-ja.com

JavaScriptデコレータを使用して適用するにはどうすればよいですか?

非常にシンプルなコードでデコレータを使用する方法を理解しようとしているので、このコンセプトをより大きなプロジェクトに適用できます。 Addy Osmaniの記事 here からヒントを得て、次のような簡単なコードを作成しました。

たとえば、Catと呼ばれるクラスにmeow()メソッドがあり、以下のようにいくつかのログで装飾したいとします。

class Cat {
  @logger
  meow() { console.log( ' Meeeoow! ') }
};


function logger(target, key, descriptor) {
  console.log("Cat snarling...");
  return descriptor;
}

const cat = new Cat();
cat.meow();

Node.jsインタープリター(バージョン9.1.0)に対してこれを実行しようとすると、次のエラーが表示されます。

/Users/ravindranath/projects/decorators/index.js:2 @logger ^ 
 
 SyntaxError:createScript(vm.js:の無効または予期しないトークン
: 80:10)
 at Object.runInThisContext(vm.js:152:10)
 at Module._compile(module.js:605:28)
 at Object.Module。 _extensions..js(module.js:652:10)
 at Module.load(module.js:560:32)
 at tryModuleLoad(module.js:503:12)
 Function.Module._load(module.js:495:3)
 at Function.Module.runMain(module.js:682:10)
 at startup(bootstrap_node.js:191 :16)
 bootstrap_node.js:613:3 

だから、私の質問は次のとおりです。

  1. Node.js 9.xはデコレータ構文をサポートしていますか?それとも、将来のバージョンで登場しますか?

  2. express-jsベースのデコレータはGitHubにありますが、自分のデコレータを作成する方法がわかりません。 Node.jsを使用してカスタムデコレータを作成する簡単な基本例を提供できますか?

デコレータは、ECMAScript 2016(別名7)のnotの一部です。現在、デコレータは ステージ2ドラフト 機能が完成して言語の一部になる前に通過する合計4段階のうちです。これらはおそらく近い将来言語に統合されるでしょうが、その機能と仕様は変更される可能性があります。このため、Babelなどのトランスパイラーを使用して、デコレータをNodeランタイムが理解できるコードに変換する必要があります(ECMAScript 2016) transform-decorators Babelプラグイン。

デコレータの作成に関しては、すでに作成済みです。各デコレータは、別のケースをラップする関数であり、ユースケースに基づいて引数が提供されます。この場合、targetkey、およびdescriptorです。 logger関数:

function logger(target, key, descriptor) {
  console.log("Cat snarling...");
  return descriptor;
}

既にデコレータです。クラスのプロパティとメソッドの場合、targetはプロパティのクラス、keyはプロパティ名、 descriptorはプロパティの記述子です。その後、デコレータが呼び出され、クラスのプロパティが Object.defineProperty 脱糖したら。あなたの例はこれに要約することができます:

class Cat { }

let meowDescriptor = {
  type: 'method',
  initializer: () => () => {
    console.log(' Meeeoow! ');
  },
  enumerable: false,
  configurable: true,
  writable: true
}

function logger(target, key, descriptor) {
  console.log("Cat snarling...");
  return descriptor;
}

meowDescriptor = logger(Cat.prototype, 'meow', meowDescriptor);
Object.defineProperty(Cat.prototype, 'meow', {
  ...meowDescriptor,
  value: meowDescriptor.initializer()
});

クラス自体の場合、デコレータは1つの引数を取ります。targetは、装飾されたクラスを記述します。私は いくつかのドキュメント を読むことをお勧めします。

10
Li357