JavaScript デコレーターの作成方法と、自動アクセサーの使用が開発者のエクスペリエンス向上にどのように役立つかについてのチュートリアル。
GitHub の Decorators Proposal は、すでにデコレータの基本的なユースケースを詳しく解説しています。私の目標は、これらの例をそこで再作成することではなく、あまり知られていない機能や相互作用に焦点を当てることです。さらに、このシリーズの次の記事では、単一のクラス プロパティで複数のデコレータを構成またはチェーンする方法について説明します。
各コード サンプルにはインタラクティブな Babel REPL プレイグラウンドへのリンクが付属しているため、ポリフィルを設定したりリポジトリをスピンアップしたりせずに、自分で試すことができます。すべての例では、左上 ([設定] の下) にある [評価] オプションをオンにする必要があります。これは、コードを表示し、編集し、ブラウザーの開発コンソールを開いて、そこでログ/結果を確認できることを意味します。
デコレータのポリフィルを詳しく調べたくない場合を除き、Babel REPL の右側にあるトランスパイルされたコードに注意を払う必要はありません。 Babel REPL の左側では、コードを編集して作成して自分で試してみることができます。
強調しておくと、開発者ツールのコンソールにはコンソール ログが表示されるはずです。そうでない場合は、左上の「評価」がチェックされていることを確認してください。
デコレーター仕様の重要な機能は自動アクセサーです。まず、それらが何であるか、そして自動アクセサーを使用するとデコレーターの作成がどのように簡単になるかを学びます。
Decorators の提案では、自動アクセサの概要がここに示されています。しかし、結局のところ、それは単純な機能です。基本的な動作例を見てみましょう: Babel REPL.
class MyClass { accessor myBoolean = false }
このクラス定義では、アクセサー キーワードがプロパティ名の前に置かれます。ただし、このプロパティに関してはまだ実際には何も変わっていません。次に、自動アクセサーがデコレーターと組み合わせたときにどのように役立つかを見ていきます。
(静的アクセサー myBoolean = false など、自動アクセサーで static を使用することもできることに注意してください)
自動アクセサーを使用する理由をよりよく理解するために、いくつかのデコレーターを構築してみましょう。
構文を理解するために、自動アクセサーと実際にはあまり機能しないデコレーターを組み合わせることから始めます。
これは、内部変数を保持し、クラスのプロパティを通じてその変数を取得および設定できるようにする関数デコレーターです: Babel REPL
function simpleDecorator(value, context) { let internalValue = false return { get() { return internalValue }, set(val) { internalValue = val return internalValue } } } class MyClass { @simpleDecorator accessor myBoolean }
このデコレータは、get() と set() の 2 つのメソッドを含むオブジェクトを返します。これは、自動アクセサーのデコレーターがプロパティのセッターとゲッターの両方を 1 つの場所で「装飾」またはラップする方法です。 simpleGetterDecorator と simpleSetterDecorator を作成する必要はありません。代わりに、自動アクセサーを使用してそれらを単一の定義に結合しました。これにより、より簡単になります。
結局のところ、これは今のところかなり普通の関数のように見えます - これは入門として最適です!
記事の残りの部分を準備するために、デコレータを更新して、実際に何らかの検証を行うようにしましょう。偶数のみを設定し、それ以外は何も設定できないデコレータを作成します。これは次のようになります: Babel REPL
function onlyEvenNumbers(value, context) { let internalNumber = 0 return { get() { return internalNumber }, set(val) { const num = Number(val) if(isNaN(num)) { // don't set the value if it's not a number or coerced to a number return internalNumber } if(num % 2 !== 0) { // don't allow odd numbers return internalNumber } internalNumber = val return internalNumber } } } class MyClass { @onlyEvenNumbers accessor myEvenNumber }
そこで、set() メソッドにロジックを追加すると、クラスに myEvenNumber プロパティを設定しようとする人は誰でもその検証ロジックを通過するようになります。ニース。
これで、偶数のみの優れたデコレーターが完成しました。次に、必要な数値のタイプを構成するオプションを使用して、偶数と奇数の両方を処理できるようにしましょう!
幸いなことに、ここで書いているのはごく普通の JavaScript なので、このように動作するように設定するのはそれほど難しくありません。元のデコレータをオプションを受け取る関数でラップし、デコレータを返します。バベルREPL
function evensOrOdds(onlyEvens = true) { return function decorator(value, context) { let internalNumber = 0 return { get() { return internalNumber }, set(val) { const num = Number(val) if(isNaN(num)) { // don't set the value if it's not a number return internalNumber } if(num % 2 !== (onlyEvens ? 0 : 1)) { return internalNumber } internalNumber = val return internalNumber } } } } class MyClass { @evensOrOdds(true) accessor myEvenNumber @evensOrOdds(false) accessor myOddNumber }
これで、デコレーターが任意のオプションを受け入れるように構成されました。これにより、デコレーターのユーザーがその動作をカスタマイズできるようになります。わーい。
デコレータが利用できる追加ツールの 1 つは context.metadata です。このオブジェクトは各デコレータに渡され、さまざまな用途に使用できますが、メタデータ オブジェクトはすべてのデコレータのすべての呼び出しで同じであるため、注意が必要です。
このシリーズの次の投稿に進み、単一のプロパティにデコレータを構成する (または複数のデコレータを適用する) 方法を学習してください。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3