TypeScript入門之利用裝飾器擴(kuò)展代碼能力
裝飾器是什么
在 TypeScript 中,裝飾器是一種特殊的聲明,可以附加到類、方法、屬性或參數(shù)上,以擴(kuò)展它們的行為或修改它們的定義。就像給一個平凡的蛋糕添加了炫目的糖衣一樣,裝飾器能讓你的代碼更有趣、更靈活。
裝飾器通過使用 @ 符號緊跟在要修飾的目標(biāo)前面來應(yīng)用,就像是給目標(biāo)貼上了一個標(biāo)簽。當(dāng)代碼運(yùn)行到裝飾器所標(biāo)記的目標(biāo)時,裝飾器就會起作用,讓你能夠在不修改目標(biāo)代碼的情況下增加新的功能或行為。
裝飾器的種類
在 TypeScript 中,我們有四種常用的裝飾器類型:類裝飾器、方法裝飾器、屬性裝飾器和參數(shù)裝飾器。下面讓我們一起來看看它們各自的特點(diǎn)和用途。
類裝飾器
類裝飾器是應(yīng)用于類構(gòu)造函數(shù)的裝飾器。它接收一個參數(shù),這個參數(shù)是被裝飾的類本身。你可以使用類裝飾器來修改類的行為、添加新的屬性或方法,甚至可以完全重寫類的定義。
舉個例子,假設(shè)我們有一個 @logged 裝飾器,它會在類被實(shí)例化時打印一條日志信息。我們可以這樣使用它:
@logged
class Calculator {
// 類的定義
}在這個例子中,當(dāng)我們創(chuàng)建 Calculator 的實(shí)例時,裝飾器 @logged 就會觸發(fā)并執(zhí)行相應(yīng)的邏輯,比如打印一條日志。
方法裝飾器
方法裝飾器應(yīng)用于類中的方法。它可以用來修改方法的行為、攔截方法的調(diào)用或者為方法添加額外的功能。
假設(shè)我們有一個 @validate 裝飾器,它會驗(yàn)證方法的參數(shù)是否符合一定的規(guī)則。我們可以這樣使用它:
class User {
@validate
setName(name: string) {
// 方法的定義
}
}在這個例子中,當(dāng)我們調(diào)用 setName 方法時,裝飾器 @validate 就會被觸發(fā),并對方法的參數(shù)進(jìn)行驗(yàn)證。
屬性裝飾器
屬性裝飾器應(yīng)用于類的屬性上。它可以用來修改屬性的行為或者給屬性添加額外的元數(shù)據(jù)。
舉個例子,假設(shè)我們有一個 @readonly 裝飾器,它會將屬性設(shè)置為只讀,防止被修改。我們可以這樣使用它:
class Person {
@readonly
name: string;
}在這個例子中,裝飾器 @readonly 會阻止對 name 屬性的修改,保持其只讀狀態(tài)。
參數(shù)裝飾器
參數(shù)裝飾器應(yīng)用于函數(shù)或方法的參數(shù)上。它可以用來修改參數(shù)的行為或者為參數(shù)添加額外的元數(shù)據(jù)。
假設(shè)我們有一個 @logParameter 裝飾器,它會在方法執(zhí)行前后記錄參數(shù)的值。我們可以這樣使用它:
class Logger {
log(@logParameter message: string) {
// 方法的定義
}
}在這個例子中,裝飾器 @logParameter 會在調(diào)用 log 方法時捕獲參數(shù)的值,并在方法執(zhí)行前后進(jìn)行記錄。
裝飾器的執(zhí)行順序
裝飾器的執(zhí)行順序是從上到下、從外到內(nèi)的。也就是說,當(dāng)一個目標(biāo)有多個裝飾器時,它們會按照從上到下的順序依次執(zhí)行。
舉個例子,假設(shè)我們有以下裝飾器:
@decorator1
@decorator2
class MyClass {
// 類的定義
}在這個例子中,裝飾器 decorator1 會先執(zhí)行,然后才輪到裝飾器 decorator2。這個順序是非常重要的,因?yàn)楹竺娴难b飾器可以在前面的裝飾器的基礎(chǔ)上進(jìn)行修改。
常見應(yīng)用場景
現(xiàn)在,我們來看看裝飾器在實(shí)際開發(fā)中的常見應(yīng)用場景。
日志記錄
通過使用裝飾器,我們可以輕松地在類或方法的調(diào)用前后記錄日志信息。這對于調(diào)試和監(jiān)控應(yīng)用程序非常有用。
function log(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
console.log(`調(diào)用方法 ${propertyKey},參數(shù): ${args.join(', ')}`);
const result = originalMethod.apply(this, args);
console.log(`方法 ${propertyKey} 執(zhí)行結(jié)果: ${result}`);
return result;
};
return descriptor;
}
class Calculator {
@log
add(a: number, b: number) {
return a + b;
}
}
const calculator = new Calculator();
calculator.add(2, 3);
// 輸出: 調(diào)用方法 add,參數(shù): 2, 3
// 方法 add 執(zhí)行結(jié)果: 5在這個例子中,我們定義了一個 log 裝飾器,它會在方法調(diào)用前后打印日志信息。
權(quán)限控制
通過裝飾器,我們可以輕松地實(shí)現(xiàn)對類或方法的權(quán)限控制。例如,我們可以為某個方法添加一個 @adminOnly 裝飾器,只有管理員才能調(diào)用該方法。
function adminOnly(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
if (!isAdmin()) {
throw new Error('無權(quán)訪問');
}
return originalMethod.apply(this, args);
};
return descriptor;
}
class UserManagement {
@adminOnly
deleteUser(userId: string) {
// 刪除用戶的邏輯
}
}
const userManagement = new UserManagement();
userManagement.deleteUser('123'); // 只有管理員才能執(zhí)行該方法在這個例子中,我們定義了一個 adminOnly 裝飾器,它會在調(diào)用方法前檢查當(dāng)前用戶是否為管理員。
常見問題與注意事項(xiàng)
使用裝飾器時,有一些常見問題和注意事項(xiàng)需要我們注意。
裝飾器的傳參問題
有些裝飾器需要接收參數(shù)來定制其行為。但是,裝飾器的寫法并不直觀,我們需要使用額外的函數(shù)來返回裝飾器本身。
舉個例子,假設(shè)我們有一個需要接收參數(shù)的裝飾器 @customDecorator,我們可以這樣定義它:
function customDecorator(parameter: any) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
// 裝飾器邏輯
};
}
class Example {
@customDecorator('參數(shù)值')
method() {
// 方法的定義
}
}在這個例子中,我們定義了一個接收參數(shù)的裝飾器 customDecorator。在使用時,我們需要調(diào)用它并傳入?yún)?shù),返回一個真正的裝飾器函數(shù)。
裝飾器對原始類型的支持問題
裝飾器通常用于修飾類、方法或?qū)傩裕⒉恢苯又С謱υ碱愋停ɡ缱址?、?shù)字)的裝飾。
舉個例子,如果我們嘗試給一個字符串變量應(yīng)用裝飾器,是不會起作用的:
@decorator const message = 'Hello, World!';
在這個例子中,裝飾器 decorator 不會對字符串變量 message 產(chǎn)生任何影響。裝飾器只能應(yīng)用于類、方法、屬性或參數(shù)。
總結(jié)
裝飾器是 TypeScript 強(qiáng)大的特性之一,它可以幫助我們在不修改源代碼的情況下擴(kuò)展和定制類、方法或?qū)傩缘男袨?。通過使用裝飾器,我們可以輕松地實(shí)現(xiàn)日志記錄、權(quán)限控制等功能。
裝飾器是一把雙刃劍,用得當(dāng)可以提升代碼的可讀性和可維護(hù)性,用得不當(dāng)可能帶來一些困惑和問題。因此,在使用裝飾器時,務(wù)必謹(jǐn)慎并深入理解其原理和用法。
到此這篇關(guān)于TypeScript入門之利用裝飾器擴(kuò)展代碼能力的文章就介紹到這了,更多相關(guān)TypeScript裝飾器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- TypeScript裝飾器的作用、結(jié)構(gòu)、類型及其應(yīng)用場景(代碼示例)
- 使用TypeScript和裝飾器實(shí)現(xiàn)前端數(shù)據(jù)脫敏
- TypeScript裝飾器之項(xiàng)目數(shù)據(jù)轉(zhuǎn)換詳解
- TypeScript裝飾器與反射元數(shù)據(jù)實(shí)例詳解
- Typescript使用裝飾器實(shí)現(xiàn)接口字段映射與Mock實(shí)例
- Typescript裝飾器AOP示例詳解
- TypeScript中的裝飾器用法
- TypeScript 裝飾器定義
- 淺談Typescript 裝飾器執(zhí)行順序
相關(guān)文章
javascript實(shí)現(xiàn)文字跑馬燈效果
這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)文字跑馬燈效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-06-06
JS實(shí)現(xiàn)用特殊符號替換字符串的中間部分區(qū)域的實(shí)例代碼
相信很多人都遇到過敏感信息需要做部分隱藏功能,大多數(shù)都是用特殊符號去替換。今天小編給大家?guī)砹薐S實(shí)現(xiàn)用特殊符號替換字符串的中間部分區(qū)域的實(shí)例代碼,需要的朋友參考下吧2018-07-07
JS簡單實(shí)現(xiàn)數(shù)組去重的方法示例
這篇文章主要介紹了JS簡單實(shí)現(xiàn)數(shù)組去重的方法,涉及javascript數(shù)組的遍歷、判斷及賦值操作,代碼非常簡單易懂,具有一定參考借鑒價值,需要的朋友可以參考下2017-03-03
部分網(wǎng)站允許空白referer的防盜鏈圖片的js破解代碼
主要是有些網(wǎng)站的圖片調(diào)用是防盜鏈的但一般只是判斷referer是不是自己網(wǎng)站,如果referer為空也會顯示圖片,所以有了下面的代碼。2011-05-05
微信小程序?qū)崿F(xiàn)錨點(diǎn)定位功能的方法實(shí)例
“錨點(diǎn)”功能在實(shí)際應(yīng)用設(shè)計(jì)的好,可以提高用戶體驗(yàn),這篇文章主要給大家介紹了關(guān)于微信小程序?qū)崿F(xiàn)錨點(diǎn)定位功能的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-07-07
async/await實(shí)現(xiàn)Promise.acll()簡介
Promise.all() 方法接收一個 promise 的 iterable 類型的輸入,并且只返回一個Promise實(shí)例,并且輸入的所有 promise 的 resolve 回調(diào)的結(jié)果是一個數(shù)組,這篇文章主要介紹了async/await實(shí)現(xiàn)Promise.acll()簡介,需要的朋友可以參考下2022-11-11

