序文: 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 均等分割 (完全三分の一) の実装
Linux での Tomcat の起動とシャットダウンLinux システムでは、コマンド操作を使用し...
<br />ブログを始めて 1 年、私はブログの内外で多くのことを個人的に学びました。ま...
目次ユニオンクエリ1. 中国の各省のIDと名前を照会する2. 湖南省のすべての地級市のIDと名称3....
1. mysqlコマンドをインポートするmysql コマンドのインポート構文は次のとおりです。 my...
目次1. nginxプロセスロックの役割2. エントリーレベルのロックの使用3. nginxプロセス...
(P4) Web 標準は一連の標準で構成されています。中心となる概念は、Web ページの構造、スタイ...
この記事では、MySQL 5.7.25圧縮版のインストールと設定方法を参考までに紹介します。具体的な...
目次1: galera-clusterの紹介2. galera-clusterの仕組み3: Mari...
目次1. binlogの紹介2. Binlog関連のパラメータ3. バイナリログの内容を分析するIV...
目次説明する成し遂げるプロジェクトのディレクトリ構造は次のとおりです。効果図は以下のとおりです要約す...
序文ミニプログラムを開発する過程では、録音機能を実装し、録音を再生し、録音をサーバーにアップロードす...
目次ダーティページ(メモリページ)ダーティページが表示されるのはなぜですか?メモリ管理メカニズムの簡...
感想:私はバックエンド開発者です。静的 (HTML) ページを取得すると、ページ構造と命名規則が極端...
序文当社の MySQL オンライン環境のほとんどはバージョン 5.7.18 を使用しています。このバ...
問題を見つける今日はTomcatのソースコードを勉強するつもりなので、公式サイトからTomcatのソ...