活字体の練習がノートに不可欠である(8) - デコレータ

  デコレータ(デコレータ)は、クラス内で宣言されてもよく(例えば、属性、メソッド、等)は、標識を提供するように、追加のロジックのための複雑なロジックの分離または追加的に、上記のメンバー、構文@expressionの形態。式は、実行時に呼び出される関数であり、そのパラメータは、ステートメント情報飾られています。@sealedデコレータがあると次のように、それをシール()関数を定義することができます。

関数封止さ(ターゲット){
   // ... 
}

  デコレータを開くための2つの方法で、以下に示すように、第1の値が「ES5」である、請求--targetパラメータを省略することができない、コマンド入力時--experimentalDecoratorsパラメータを追加することがあります。

TSC デフォルト .TS --target ES5 --experimentalDecorators

  対応するターゲットプロパティを省略することができない、以下に示すように、第2の属性は、プロファイルtsconfig.json experimentalDecoratorsを添加します。

{ 
  compilerOptions:{ 
    ターゲット: "ES5" 
    experimentalDecorators:
  } 
}

クラスデコレータ

  唯一の装飾デバイスは、そのパラメータを受け取ることができるように、クラスのデコレータモニターのコンストラクタ、クラスや種類を変更したり、交換してください。装飾的な戻りが不定と、元のコンストラクタの延長;装飾的価値が戻ったときに、元のコンストラクタをカバーするために使用されるであろう。クラスが前に宣言@sealed前記次の例では、クラスを囲むプロトタイプクラスのコンストラクタとデコレータを通過します。

@sealed
 クラス人{ 
  名:文字列
  コンストラクタ(名前:文字列){
     この .nameの= 名前。
  } 
} 
関数封止さ(コンストラクタファンクション){ 
  Object.seal(コンストラクタ)。
  Object.seal(constructor.prototype)。
}

  活字体は、コンパイル後、__decorated()関数が生成され、そして以下に示すように、Personクラスに適用されます。

VAR人= / * * @class * /関数(){
   関数人(名前){
     この .nameの= 名; 
  }  = __decorate([封止さ]、人);
   戻り人; 
})();

  クラスのデコレータ.d.tsが宣言ファイルおよび外部クラスには表示されないことに注意してください。

第二に、メソッドのデコレータ

  クラスのデコレータ過負荷制限より多くのよりも、プロセスの属性記述子に作用する前に、クラス宣言のための装飾の方法。下に記載されているように、それは、3つのパラメータを受け取ります:

  (1)静的な部材は、例えば、オブジェクト・クラスのメンバーはプロトタイプである、クラスのコンストラクタです。

  (2)メンバー、文字列又はシンボル名。

  (3)属性記述子のメンバー、出力はES5バージョン未満である場合、この値は不定となります。

  この方法は、装飾的な値を返すときに、属性記述子には、現在のメソッドを上書きします。以下に単純な例で、最初のパラメータはデコレータPerson.prototype方法で、第二は、「カバー」、呼び出しのgetName()メソッドではなく、元の「ストリック」を、「自由」を得られるであろうあります。

クラス人{ 
  @cover 
  のgetName(名){ 
    戻り名。
  } 
} 
関数カバー(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
  descriptor.value = 関数(){
     戻り " 自由" 
  }。
  戻り値の記述。
} 
人ましょう = 新しい人を(); 
person.getName(" ストリック");        // 「自由」

第三に、アクセサデコレータ

  アクセサデコレータは、同じ3つのパラメータとメソッドのデコレータを受けながら、同じクラスの装飾に制限されている対応する属性記述子の役割をクラスのプロパティにアクセスする前に宣言しました。装飾getおよびsetアクセサのメンバーは、最初のアクセサに適用することができながらも、それを注意する必要がある、活字体が許可されていません。

  以下のPersonクラスでは、アクセスされた場合例えば、アクセサプロパティ名を定義し、むしろオリジナルの「ストリック」よりも、「自由」を取得します。

クラス人{
   プライベート _name:文字列; 
  @access 
  取得名前を(){
     返す この._nameを。
  } 
  セットの名前(名){
     この ._name = 名。
  } 
} 
関数アクセス(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
  ディスクリプタ。GET = 関数(){
     リターン " 自由" 
  }。
  戻り値の記述。
} 
人ましょう = 新しい人を(); 
person.name= " ストリック" ; 
console.log(person.name)。        // 「自由」

第四に、プロパティデコレータ

  同じではありませんが、唯一の2つのパラメータを取り、第三属性記述子パラメータが存在しない、と戻り値デコレータへのアクセスを制限装飾性の前に属性宣言、。それでもPersonクラスの下に、例えば、name属性とその値に変更@propertyデコレータを定義します。

クラス人{ 
  @propertyの
  名:文字列
} 
機能性(標的:任意のキー:文字列){ 
  Object.defineProperty(ターゲット、キー、{ 
    値:" 自由" 
  })。
} 
人ましょう = 新しい人を(); 
person.name = " ストリック" ; 
console.log(person.name)。        // 「自由」

5つのパラメータデコレータ

  パラメータ宣言前デコレータパラメータは、それがデコレータを制限する方法と同様であり、値を返さず、3つのパラメータを受け取ることができ、第三のパラメータは位置を表す関数のパラメータリストの装飾パラメータ(すなわちインデックス)。ここで使用パラメータのデコレータを実証する例、方法がデコレータで作業する必要があります。

聞かせてのparams = [];
クラス人{ 
  @func 
  のgetName(@required名){ 
    戻り名。
  } 
}

  以下に示すように、位置指定修飾パラメータ値のために必要@コールのgetName()メソッドは、その入力値のparams配列、@Func。

関数FUNC(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
  CONST方法 = descriptor.value。
  descriptor.value = 関数(){
     戻り method.apply(この、paramsは)。
  }。
  戻り値の記述。
} 
関数必要な(標的:任意、キー:文字列、インデックス:数){ 
  paramsは[インデックス] = "自由" 
}

  Personクラスをインスタンス化すると、コールのgetName()メソッドは、「自由」を得られることになります。

聞かせて人= 新しい人(); 
person.getName( "ストリック");        // 「自由」

第六に、装飾工場

  デコレータ植物は、任意の関数の引数、それが使いやすいラップするために使用されるデコレータを受信することができる、それは上記の機能のデコレータのいずれかに戻ることができます。次に、カバー()関数でデコレータを改造する方法は、以下のような方法がデコレータ機能を返し、文字列パラメータ・タイプの値をとります。

関数カバー(値:文字列){
   リターン 機能(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
    descriptor.value = 関数(){
       戻り値。
    }。
    戻り値の記述。
  }。
}

  @coverクラスのメソッドに適用された場合、必要性は、以下のように、文字列を渡します。

クラス人{ 
  @cover(" 自由" 
  のgetName(名){ 
    リターン名。
  } 
}

七つの装飾の組み合わせ

  同じ装飾複数のステートメントに適用する場合、以下のように書くことができる行は、複数行に書き込まれてもよいです。

/ * *****ライン***** * / 
@first @second DESC 
/ * ***** *****複数行* / 
@first 
@second 
DESC

  合成と同様、これらの装飾的な機能は、第一連続底呼び出しから、その後、評価結果の関数として、下デコレータ上から行わ方法を評価しました。例えば、工場は、次のコードに示すように、番号が本体と復帰機能デコレータに印刷され、2つの装飾的な機能を定義します。

機能最初の(){ 
  にconsole.log( 1 )。
  リターン 機能(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
    にconsole.log( 2 )。
  }。
} 
関数秒(){ 
  にconsole.log( 3 )。
  リターン 機能(目標:任意、キー:文字列、記述子:のPropertyDescriptor){ 
    にconsole.log( 4 )。
  }。
}

  次のコードに示すように、それらは、クラス内の同じメソッドを宣言しなければなりません。評価の順序は、1と3,2と4をプリントアウトし、見て、次にプリントアウトすることができます。

クラス人{ 
  @first()
  @second()
  のgetName(名){ 
    戻り名。
  } 
}

 

おすすめ

転載: www.cnblogs.com/strick/p/11792566.html