JavaScriptのデコレータスピードガイド

:この記事はで再現された猿2048ウェブサイト➝ https://www.mk2048.com/blog/blog.php?id=hj1jk2cb0j


デコレータJavaScriptはES7の新機能が追加されています。活字学生は、活字体、この機能へのアクセス以前に精通している必要がありますか?以前使用デコレータをサポートするだけでなく、ES5のためのサポートを提供していました。??記事?デコレータは、詳細な説明を行いますが、私はあなたがプログラミングの利便性と優雅さのためにそれを経験することになると信じています。

私はフルタイムのフロントエンドの開発を行う前に、彼は「機能」で、.NETのための専門の.NETプログラマは非常に身近な使用です。特性を初期化ブラケットブラケット、上のクラス、メソッドまたはプロパティに書き込まれ、それは、クラス、メソッドまたはプロパティの挙動に影響を与えるであろう。これはちょうど魔法のように、AOPプログラミングだけでなく、ORMフレームワークに特に有用です。しかし、JavaScriptはそのような機能がないとき。活字体で初めて使用されているデコレータ、我々はアプリケーション全体をしたいので?治療のシーケンスを作成するためのプログラムに関するコンテキスト情報、オリジナルのドメインモデルでは、簡単な方法がありますか?かどうか直列化された識別するためのラベルでマーク挙動制御の直列化は、このようなシナリオデコレータは、その力を演じます。その後、我々はシリーズまたはビューのデカップリングポイントの利便性から、驚くべき効果があったかどうかデコレータ場合、変数クラス定義と不変オブジェクトのアプリケーション間の切り替えを、当社の状態管理を再構築する必要があります。デコレータは、一般的な文書の使用に関連を整理するために、このトピックを説明する最も簡単な方法を試してきた、私は書きませんでした。誤ってネットワーク(https://cabbageapps.com/fell-love-js-decorators/)、まさに私が次に,?表明撮りたい、この記事の内容や文言に一致する記事を発見?是非、再びそれを行います編集と適応。見たい?英語学生がオリジナルを読むためにリンクをクリックすることができます。

1.0デコレーター

我々は検索エンジンの検索結果と関連するプログラミングで「装飾」または「デコレータ」を検索し直接場合は、Decoratorパターンのデザインパターンの導入が表示されます。

次のようにもっと直感的な例は以下のとおりです。

上記WeaponAccessory図はデコレータで、彼らは追加しますか?追加の方法と基本クラスに馴染みが。それはあなたが理解していない場合は関係ありません、私はあなたの?自分のデコレータを達成するためのステップバイステップに従う、自然に理解するだろう。下の写真は、あなたが直感的にデコレータを理解するのに役立ちます。

5.gif

私たちは、単にそれがオブジェクト、メソッド、おなじみ?パッケージのパッケージと考えることができ、デコレータを理解しています。我々は、オブジェクトの周囲をアクセスするには、このパッケージを渡すと、オブジェクトにアクセスする必要がある場合には、その後、このパッケージ?添付動作がトリガされますです。たとえば?サイレンサー銃を追加しました。マフラーは飾りですが、それはマフラーが役割を果たします際に発砲し、全体として銃を判明しました。

オブジェクト指向の概念の観点から十分に理解されています。だから、どのように我々はJavaScriptでデコレータを使うのですか?

1.1ツアー開始デコレータ

デコレータは、新しい?特性をサポートしていますか?ES7ですが、バベルとTypesScriptで、我々は今、TypesScript例この紙を使用することができます。

まずtrueにtsconfig.jsonファイル、設定experimentalDecoratorsとemitDecoratorMetadataを変更します。

{
  "compilerOptions": {
    "target": "es2015",
    "module": "commonjs",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true
  },
  "exclude": [
    "node_modules",
  ]
}

私たちは、その後の分析の層を開始する効果で始まり、そして。以下のコードを見てください:

function leDecorator(target, propertyKey: string, descriptor: PropertyDescriptor): any {
    var oldValue = descriptor.value;

    descriptor.value = function() {
      console.log(`Calling "${propertyKey}" with`, arguments,target);
      let value = oldValue.apply(null, [arguments[1], arguments[0]]);

      console.log(`Function is executed`);
      return value + "; This is awesome";
    };

    return descriptor;
  }

  class JSMeetup {
    speaker = "Ruban";
    //@leDecorator
    welcome(arg1, arg2) {
      console.log(`Arguments Received are ${arg1} ${arg2}`);
      return `${arg1} ${arg2}`;
    }
  }

  const meetup = new JSMeetup();

  console.log(meetup.welcome("World", "Hello"));

?次のように上記のコードを実行し、結果は以下のとおりです。

コード、コメント行17リリースを修正してみましょう。

次のようにもう一度コードを実行し、結果は以下のとおりです。

左、右側上記出力画像はコード?行番号を示していることに留意されたいです。私たちは今?確かに、その後、@leDecoratorラベルが追加、機能歓迎動作が変更されました,?どこleDecoratorは、機能の変更をトリガされることができます。デコレータの顔に私たちの基本的な理解によると、私たちはleDecoratorは歓迎デコレータも考えることができます。デコレータと@演算子で接続されているデコレータの間

JavaScriptでは、私たちは私たちのコードは装飾的な機能である,?デコレータの感情的な理解度を持っています。JavaScriptでは、四つのカテゴリーデコレーターの合計?:

  • メソッドのデコレータ関数デコレータ
  • プロパティデコレータおなじみのデコレータ
  • クラスデコレータークラスデコレータ
  • パラメータパラメータデコレーターデコレータ

?ここでは、一つ一つを破ります!さあ!

1.2関数デコレータ

最初は、このセクションでは、この記事の核心内容である、デコレータは関数デコレータで妥協することが、我々はJavaScriptのデコレータの性質にに?洞察デコレータを機能するように説明します。

関数デコレータを使用することにより、我々は、入力と出力の機能を制御することができます。

ここではデコレータの関数の定義は次のとおりです。

MethodDecorator = <T>(target: Object, key: string, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | Void;

?ただ、次のように3つのパラメータを意味し、我々は関数デコレータをカスタマイズすることができ、上記の定義に従ってください。

  • ターゲット - ?>装飾されたオブジェクト
  • キー - >装飾された関数名
  • ディスクリプタ - >属性記述子のプロパティを介して送信されObject.getOwnPropertyDescriptor属性記述子()メソッドによって見ることができます。

属性記述子は、より詳細な情報https://www.jianshu.com/p/19529527df80を参照することができます。

簡単に言えば、プロパティ記述子には、オブジェクトの戻り値のプロパティを設定/セット振る舞い、削除することができ、変更することができ、それが列挙できる特性を取得するために使用することができます。私たちは?少し直感的な例を見て下にあなたは、デコレータを滑らかにできることを理解するために。

ブラウザのコンソールを開き、次のコードを入力してください:?

var o, d;
var o = { get foo() { return 17; }, bar:17, foobar:function(){return "FooBar"} };

d = Object.getOwnPropertyDescriptor(o, 'foo');
console.log(d);
d = Object.getOwnPropertyDescriptor(o, 'bar');
console.log(d);
d = Object.getOwnPropertyDescriptor(o, 'foobar');
console.log(d);

結果は以下の通りであります:

ここでは、オブジェクトoを定義し、それから、3つのプロパティ--foo、バー、foobarのを定義する?Object.getOwnPropertyDescriptor(したもの)?各属性記述子とそれらをプリントアウト。値、列挙、設定可能と書き込み可能の簡単な説明をしてみましょう。

  • 値 - リテラル>リターン値や関数/プロパティの計算。
  • 列挙 - (あなたが列挙できるかどうか)は、objでのxについて(サイクルをアウト?)>列挙することができます
  • >属性が設定できるかどうか - 設定可能
  • 書き込み可能? - >プロパティが書き込み可能であるかどうか。

各メソッドは、独自のプロパティまたは記述子を持って、我々は、記述子または戻り値によってプロパティの動作を変更することができます。ここでは、次のキー:

エッセンスデコレータは記述を修正します

デコレータの手を書く時間です。

1.2.1?デコレータのインスタンスメソッド

ここでは、メソッドのデコレータで関数の入力と出力を変更します。

function leDecorator(target, propertyKey: string, descriptor: PropertyDescriptor): any {
    var oldValue = descriptor.value;

    descriptor.value = function() {
      console.log(`Calling "${propertyKey}" with`, arguments,target);
      // Executing the original function interchanging the arguments
      let value = oldValue.apply(null, [arguments[1], arguments[0]]);
      //returning a modified value
      return value + "; This is awesome";
    };

    return descriptor;
  }

  class JSMeetup {
    speaker = "Ruban";
    //@leDecorator
    welcome(arg1, arg2) {
      console.log(`Arguments Received are ${arg1}, ${arg2}`);
      return `${arg1} ${arg2}`;
    }
  }

  const meetup = new JSMeetup();

  console.log(meetup.welcome("World", "Hello"));

?デコレータ使用しないときは、出力値:

Arguments Received are World, Hello
World Hello

装飾を有効に、出力値:

Calling "welcome" with { '0': 'World', '1': 'Hello' } JSMeetup {}
Arguments Received are Hello, World
Hello World; This is awesome

私たちは、髪の出力値は、メソッドの変更になったことがわかります。今、私たちは、パラメータによって定義されたメソッドのデコレータを参照してください、leDecorator実行時に呼び出し元のオブジェクトの名前を取得する?装飾が施さ方法?パラメータがメソッドを飾る記述子です。まずOLDVALUE変数?元の値のメソッドの記述によって保存され、それは我々が定義された歓迎の方法です。次に、descriptor.valueが再割り当てされて。

新機能では最初の戻り値を取得するために、元の関数を呼び出し、戻り値を変更します。最後の記述子を返し、新しい記述子がこの時間積分機能本体が交換された、方法を歓迎するために適用されます。

デコレータを使用することにより、我々は、元の包装の機能を実現し、あなたは私たちがターゲットメソッドに所望の魔法効果の多様性を適用することができることを意味しており、入力および出力方法を変更することができます。

ここで注意すべきいくつかの場所は以下のとおりです。

  • クラスは、クラスのインスタンスではないと宣言されたときにデコレーションが実行されます。
  • この方法は、値のデコレータを返します
  • 元の記述子を格納し、新しいディスクリプタを返すことは推奨されるアプローチである。これは、マルチシーン記述子の用途に有用です。
  • 記述子の設定値は、矢印の機能を使用しないでください。

今、私たちは完了し、第一の方法デコレータを理解しています。ここでは、学校の財産デコレータに来ます。

1.3プロパティのデコレータ

プロパティを通じてプロパティとメソッドデコレータデコレータは非常に似ている、デコレータは、我々は可算、設定可能な属性を、ゲッター、セッターを再定義変更するために使用することができます。

次のようにデコレータ属性が定義されています。

PropertyDecorator = (target: Object, key: string) => void;

パラメータは次のとおりです。

  • 対象:不動産所有者
  • キー:属性名

特定のプロパティのデコレータを使用する前に、のはObject.defineProperty方法を簡単に見てみましょう。Object.defineProperty方法は、多くの場合、動的なオブジェクトを与えるために使用される?の追加またはプロパティを変更します。以下はサンプルです。

var o = { get foo() { return 17; }, bar:17, foobar:function(){return "FooBar"} };

Object.defineProperty(o, 'myProperty', {
get: function () {
return this['myProperty'];
},
set: function (val) {
this['myProperty'] = val;
},
enumerable:true,
configurable:true
});

上記試験のデバッグコンソールコード。

この結果から、我々はObject.definePropertyの使用は、我々は動的なオブジェクトを追加していることがわかりプロパティに追加されます。単純なプロパティデコレータを実装するためのベースObject.definePropertyをしてみましょう。

function realName(target, key: string): any {
    // property value
    var _val = target[key];

    // property getter
    var getter = function () {
      return "Ragularuban(" + _val + ")";
    };

    // property setter
    var setter = function (newVal) {
      _val = newVal;
    };

    // Create new property with getter and setter
    Object.defineProperty(target, key, {
      get: getter,
      set: setter
    });
  }

  class JSMeetup {
    //@realName
    public myName = "Ruban";
    constructor() {
    }
    greet() {
      return "Hi, I'm " + this.myName;
    }
  }

  const meetup = new JSMeetup();
  console.log(meetup.greet());
  meetup.myName = "Ragul";
  console.log(meetup.greet());

?ときNAデコレータ、出力は次のようになります。

Hi, I'm Ruban
Hi, I'm Ragul

あなたはデコレータを有効にした後、結果は次のとおりです。

Hi, I'm Ragularuban(Ruban)
Hi, I'm Ragularuban(Ragul)

それは単純ではないですか?クラスのデコレータが続きます。

1.4クラスのデコレータ

クラスは、動的プロパティとメソッドとクラスの変更を追加するために、クラスのコンストラクタの操作によって装飾されます。ここでは、クラスのデコレータの定義は次のとおりです。

ClassDecorator = <TFunction extends Function>(target: TFunction) => TFunction;

ClassDecoratorは唯一つのパラメータ、クラスのコンストラクタを受けます。次のサンプルコードは、オリジナルのスピーカークラスのプロパティを変更し、余分な動的属性を追加します。

function AwesomeMeetup<T extends { new (...args: any[]): {} }>(constructor: T) {
    return class extends constructor implements extra {
      speaker: string = "Ragularuban";
      extra = "Tadah!";
    }
  }

  //@AwesomeMeetup
  class JSMeetup {
    public speaker = "Ruban";
    constructor() {
    }
    greet() {
      return "Hi, I'm " + this.speaker;
    }
  }

  interface extra {
    extra: string;
  }

  const meetup = new JSMeetup() as JSMeetup & extra;
  console.log(meetup.greet());
  console.log(meetup.extra);

出力は装飾的価値を有効にされていない場合には:

有効デコレータの場合、出力は次のようになります。

ことに留意すべきであるコンストラクタは一度だけ呼ばれます

今、私は最後のデコレータ、デコレータパラメータを学びに来ます。

1.5パラメータのデコレータ

デコレータでデコレータの役割を推測するためのパラメータは、上記の言っている場合、それはパラメータを変更することではなく、実際にはない場合があります。デコレータパラメータは、多くの場合、特定のパラメータをマークするために使用され、プロセスデコレータ、さらにアクションに対応するタグを読み取るれます。例えば:

function logParameter(target: any, key: string, index: number) {
    var metadataKey = `myMetaData`;
    if (Array.isArray(target[metadataKey])) {
      target[metadataKey].push(index);
    }
    else {
      target[metadataKey] = [index];
    }
  }

  function logMethod(target, key: string, descriptor: any): any {
    var originalMethod = descriptor.value;
    descriptor.value = function (...args: any[]) {

      var metadataKey = `myMetaData`;
      var indices = target[metadataKey];
      console.log('indices', indices);
      for (var i = 0; i < args.length; i++) {

        if (indices.indexOf(i) !== -1) {
          console.log("Found a marked parameter at index" + i);
          args[i] = "Abrakadabra";
        }
      }
      var result = originalMethod.apply(this, args);
      return result;

    }
    return descriptor;
  }

  class JSMeetup {
    //@logMethod
    public saySomething(something: string, @logParameter somethingElse: string): string {
      return something + " : " + somethingElse;
    }
  }

  let meetup = new JSMeetup();

  console.log(meetup.saySomething("something", "Something Else"));

上記のコードは、私たちは、指定された配列に装飾パラメータを飾られるパラメータデコレータを定義しています。方法デコレータでは、ケースさらなる処理がデコレータ、次の出力が有効になっていない標識されたパラメータを見つけます:?

デコレータは次のように出力結果は、有効:

1.6まとめ

今、私たちはすべてのデコレータを使用することを学んできたことを、次のようにキーの使用を要約します?:

  • コアメソッドは、メソッドのデコレータ記述子であります
  • コア属性デコレータはObject.definePropertyです
  • コアクラスは、コンストラクタデコレータです
  • デコレータの役割の主なパラメータは、メソッドのデコレータと組み合わせて使用​​される、標識され

テキスト、懸念マイクロチャネルのサブスクリプション番号「神秘的な魂のスタジオ」返信「QD」へのより良いフロントエンド

神秘的な魂のスタジオ
ここでは、参照記事は次のとおりです。https://www.typescriptlang.org/docs/handbook/decorators.html

https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Decorators.md

https://survivejs.com/react/appendices/understanding-decorators/

https://medium.com/google-developers/exploring-es7-decorators-76ecb65fb841

https://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from-novice-to-expert-part-ii https://github.com/arolson101/typescript-decorators


より専門的なフロントエンドの知識、作る [2048] APE www.mk2048.comを

おすすめ

転載: www.cnblogs.com/jiangshangbulao/p/11780564.html