序文: 1. コンセプト1.1 定義デコレータは、クラス宣言、メソッド、アクセサー、プロパティ、およびパラメータに適用できる新しいタイプの宣言です。デコレータは、 @ 記号と関数名 (例: デコレータは変更するコンテンツの直前に配置する必要があり、すべてのデコレータは宣言ファイルや外部コンテキスト ( デコレータの定義と使用方法は次のとおりです。 // 使用する関数をデコレータ関数として定義します function testDecorator() {} // @ シンボルを介してデコレータ @testDecorator を使用する 1.2 デコレータファクトリーいわゆるデコレータファクトリも関数です。通常のデコレータ関数との違いは、戻り値が関数であり、返された関数がデコレータによって呼び出される関数として使用されることです。デコレータファクトリを使用する場合、使用時に現在の使用状況に応じて異なるパラメータを渡すことができますが、使用時に関数呼び出しを追加する必要があります。 サンプルコードは次のとおりです。 // デコレータファクトリ、戻り値は関数です function testDecorator() { 関数() を返す {} } // @symbol + 関数呼び出しでデコレータ @testDecorator() を使用する 1.3 デコレータの組み合わせデコレータは組み合わせて使用できます。つまり、1 つのターゲットを使用して複数のデコレータを参照できます。 サンプルコードは次のとおりです。 // 2つのデコレータ関数を定義します。function setName() {} 関数 setAge() {} //デコレータ@setNameを使用する @set年齢 クラス Person {} 複数のデコレータが使用されている場合、デコレータは順番に実行され、実行順序は次のようになります。 通常のデコレータ関数を使用する場合、実行順序は下から上になります。 サンプルコードは次のとおりです。 関数setName(コンストラクタ: any) { console.log('setName', コンストラクター) } 関数setAge(コンストラクタ: any) { console.log('setAge', コンストラクター) } @setName @set年齢 クラス Person {} /* 実行結果は以下のとおりです。 setAge [関数: 人] setName [関数: 人] */ デコレータ ファクトリの場合、その実行順序は、ファクトリ関数を上から下に実行し、次にファクトリ関数によって返された関数を下から上に実行します。サンプルコードは次のとおりです 関数setName() { console.log('getsetName') を実行します。 関数を返す(コンストラクタ:任意){ console.log('setName', コンストラクター) } } 関数setAge() { console.log('get setAge') 関数を返す(コンストラクタ:任意){ console.log('setAge', コンストラクター) } } @setName() @set年齢() クラス Person {} /* 実行結果は以下のとおりです。 setName を取得する 年齢設定を取得する setAge [関数: 人] setName [関数: 人] */ 1.4 デコレータの評価クラス定義内の異なる宣言のデコレータは、以下に指定された順序で適用されます。
2. クラスデコレータクラス デコレータはクラス宣言の前に使用され、装飾するコンテンツの直前に配置する必要があります。クラス デコレータはクラス宣言に適用されます。 クラス デコレータ式は実行時に関数として呼び出され、このクラスのコンストラクターである 1 つのパラメーターを持ちます。 サンプルコードは次のとおりです。 記号 = null とする 関数setName() { 関数を返す (コンストラクタ: Function) { 記号 = コンストラクタ } } @setName() クラス情報{ コンストラクタ() {} } console.log(sign === Info) // true console.log(sign === Info.prototype.constructor) // true 上記のコードから、クラス デコレータを使用して、クラスのプロトタイプ オブジェクトとコンストラクターを変更することもできます。サンプル コードは次のとおりです。 // * プロトタイプオブジェクトとコンストラクタ関数を変更する addName(constructor: { new (): any }) { constructor.prototype.name = '一碗の周' } @名前を追加 クラス Person {} 定数 person = 新しい Person() console.log(person.name) // エラー プロパティ「name」はタイプ「A」に存在しません 上記のコードでは、 サンプルコードは次のとおりです。 関数 addName(コンストラクタ: { new (): any }) { コンストラクター.prototype.name = '一碗の周' } @名前を追加 クラス Person {} 定数 person = 新しい Person() // 1. 型アサーション // console.log((person as any).name) // 一碗周 // 2. 同じ名前のインターフェースを定義し、マージインターフェースを宣言する Person { 名前: 文字列 } console.log(person.name) // 周一万 また、デコレータを介してコンストラクターをオーバーロードすることもできます。サンプル コードは次のとおりです。 // * コンストラクタ関数をオーバーロードします classDecorator<T extends { new (...args: any[]): {} }>( コンストラクタ: T, ){ 戻りクラスはコンストラクタを拡張します { 名前 = '一碗の周' 趣味 = 「コーディング」 } } @クラスデコレータ クラス Person { 年齢 = 18 名前: 文字列 コンストラクタ(名前: 文字列) { this.name = 名前 } } const person = new Person('Yiwan Zhou') console.log(人) /* 実行結果は以下のとおりです。 { 年齢: 18歳 名前:「周の一杯」 趣味:「コーディング」 } */ デコレータ ファクトリを通じてパラメータを渡すこともできます。サンプル コードは次のとおりです。 // デコレータファクトリー関数を定義する classDecorator(_name: string) { 関数 <T extends { new (...args: any[]): {} }>(コンストラクタ: T) { を返します。 戻りクラスはコンストラクタを拡張します { 名前 = _名前 趣味 = 「コーディング」 } } } @classDecorator('一碗の周') クラス Person { 年齢 = 18 名前: 文字列 コンストラクタ(名前: 文字列) { this.name = 名前 } } const person = new Person('お粥一杯') console.log(人) /* 実行結果は以下のとおりです。 { 年齢: 18歳 名前:「周の一杯」 趣味:「コーディング」 } */ 3. メソッドデコレータメソッド デコレータは、クラス内のメソッドを処理するために使用されます。メソッドのプロパティ記述子 (プロパティ記述子については、Object.defineProperty() を参照してください) とメソッド定義を処理できます。メソッド デコレータも実行時に関数として呼び出され、3 つのパラメータが含まれます。 詳細は以下の通りです。 静的メンバーの場合はクラス コンストラクター、インスタンス メンバーの場合はクラス プロトタイプ オブジェクトです。 メンバーの名。 メンバーのプロパティ記述子。 コード出力が ES5 未満のバージョンを対象としている場合、プロパティ記述子は 次のコードは、デコレータ ファクトリを通じて単純なメソッド デコレータを定義します。サンプル コードは次のとおりです。 // デコレータファクトリー関数 enumerable(bool: boolean) { /** * メソッド デコレータは 3 つのパラメータを受け入れます。 * 1. ターゲット: 静的メンバーの場合はクラスのコンストラクタ、インスタンス メンバーの場合はクラスのプロトタイプ オブジェクトです。* 2. propertyName: メンバーの名前。* 3. 記述子: プロパティ記述子。その型は PropertyDescriptor です。 */ 戻り関数( 対象: 任意、 プロパティ名: 文字列、 記述子: PropertyDescriptor、 ){ //渡されたbool記述子に基づいてメソッドが列挙可能かどうかを判断します。enumerable = bool } } クラス情報{ コンストラクター(パブリック名: 文字列) {} @列挙可能(false) 取得名() { this.name を返す } } const info = new Info('今週の一杯') // 直接印刷する場合、メソッドは列挙可能ではないため、オブジェクトには getName() メソッドが含まれません。 console.log(info) // { name: 'Yiwan Zhou' } // ただし、このメソッドは console.log(info.getName()) で呼び出すことができます // Yiwan Zhou 上記のコードでは、デコレータを通じてクラス内のメソッドのプロパティ記述子を直接変更しました。 メソッド デコレータが値を返す場合、この値はメソッドのプロパティ記述子オブジェクトとして使用されます。サンプル コードは次のとおりです。 // デコレータファクトリー関数 enumerable(bool: boolean) { 戻り関数( 対象: 任意、 プロパティ名: 文字列、 記述子: PropertyDescriptor、 ){ 戻る { 値: 関数 () { 「エラー: 名前が未定義です」を返します }, 列挙可能: ブール値、 } } } クラス情報{ コンストラクター(パブリック名: 文字列) {} @列挙可能(false) 取得名() { this.name を返す } } const info = new Info('A bowl of Zhou') console.log(info) // { name: 'Yiwan Zhou' } console.log(info.getName()) // エラー: 名前が未定義です 上記のコードでは、メソッド デコレータは、値プロパティがメソッド定義を変更するオブジェクトを返すため、最終結果は 4. アクセサデコレータアクセサ デコレータは、前に学習した アクセサ デコレータもメソッド デコレータと同様に 3 つのパラメータを受け入れるため、ここでは詳細には説明しません。 サンプルコードは次のとおりです。 関数列挙可能(bool: boolean) { 戻り関数( 対象: 任意、 プロパティ名: 文字列、 記述子: PropertyDescriptor、 ){ 記述子.enumerable = bool } } クラス情報{ private_name: 文字列 コンストラクタ(名前: 文字列) { this._name = 名前 } @列挙可能(false) 名前を取得する() { this._name を返す } 名前を設定する(名前) { this._name = 名前 } }
5. プロパティデコレータープロパティ デコレータはプロパティ宣言の前に宣言され、次に示すように 2 つのパラメータを持ちます。
サンプルコードは次のとおりです。 関数 printPropertyName(ターゲット: 任意、プロパティ名: 文字列) { console.log(プロパティ名) } クラス情報{ @printプロパティ名 名前: 文字列 @printプロパティ名 年齢: 番号 コンストラクター(名前: 文字列、年齢: 数値) { this.name = 名前 this.age = 年齢 } } 新しい情報('Yiwan Zhou'、18) 実行結果は次のとおりです。
6. パラメータデコレータパラメータ デコレータには次の 3 つのパラメータがあります。
パラメータ デコレータの機能は、メソッド パラメータが渡されたかどうかを監視することです。パラメータ デコレータの戻り値は無視されます。 サンプルコードは次のとおりです。 関数が必要です(ターゲット: 任意、プロパティ名: 文字列、インデックス: 数値) { console.log(`変更されたパラメータは ${propertyName} の ${index + 1} 番目のパラメータです`) } クラス情報{ name: string = '一碗の周' 年齢: 番号 = 18 getInfo(プレフィックス: 文字列、@必須情報タイプ: 文字列): 任意 { プレフィックス + ' ' + this[infoType] を返す } } インターフェース情報{ [キー: 文字列]: 文字列 | 数値 | 関数 } const info = 新しい Info() info.getInfo('', 'age') // getInfoの2番目のパラメータを変更します ここでは TypeScript デコレータ定義に関する記事はこれで終わりです。TypeScript デコレータについてさらに詳しく知りたい方は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続きご覧ください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: 親コンテナの CSS 均等分割 (完全三分の一) の実装
1. ホットリンクの原則1.1 Webページの準備Web ソース ホスト (192.168.153...
1. DOCTYPE は必須です。ブラウザは宣言した DOCTYPE に基づいてページのレンダリング...
序文日常の開発では、テキストの水平スクロール効果(一般にカルーセルと呼ばれる)によく遭遇します。これ...
H タグ、特に h1 タグの使用は常に議論の的となっている問題であり、私たちが研究する価値のある問題...
目次トリガーとは何かトリガーを作成するMySQL 作成構文のキーワードの説明: 1. MySQL ト...
目次序文例まとめ序文Vue の親子コンポーネントは、props を通じて親コンポーネントの値を子コン...
必要: vue を使用して QR コードのスキャンを実現します。プラグイン: QRコードリーダー;プ...
目次スタイルスコープスタイルモジュール状態駆動型動的CSS要約するスタイルスコープ注意事項:スタイル...
ユーザーとグループの管理1. ユーザーとグループの基本概念ユーザーとグループ:システム上のすべてのプ...
今日ふと、HTML でチェックボックスのスタイルを変更できる範囲が限られていることと、チェックボック...
html4:コードをコピーコードは次のとおりです。 <フォーム> <p>&l...
イメージを構築するイメージを構築するには、主に 2 つの方法があります。実行中のコンテナをイメージに...
フロントエンドの開発過程で、チェックボックスが必要な状況が発生しました。ユーザー操作の利便性を考慮し...
目次VueUse にはどのようなユーティリティがありますか? VueUseをVueプロジェクトにイン...
目次1. setTimeout() タイマー2. setTimeout() タイマーを停止する3. ...