淺談Typescript 裝飾器執(zhí)行順序
TypeScript 中裝飾器的執(zhí)行順序遵循一套固定的規(guī)則,可以從同一聲明上的多個裝飾器和類中不同成員的裝飾器兩個維度來理解。
1. 同一聲明上多個裝飾器的順序
當一個聲明(如類、方法、屬性)上應(yīng)用了多個裝飾器時:
- 裝飾器表達式(工廠函數(shù))的求值順序:從上到下。
- 裝飾器函數(shù)(返回的函數(shù)本身)的執(zhí)行順序:從下到上。
function first() {
console.log('first(): 工廠求值');
return function (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
console.log('first(): 裝飾器執(zhí)行');
};
}
function second() {
console.log('second(): 工廠求值');
return function (target: any, propertyKey?: string, descriptor?: PropertyDescriptor) {
console.log('second(): 裝飾器執(zhí)行');
};
}
class Example {
@first()
@second()
method() {}
}
輸出順序:
first(): 工廠求值
second(): 工廠求值
second(): 裝飾器執(zhí)行
first(): 裝飾器執(zhí)行
2. 類中不同成員裝飾器的整體順序
對于類中的不同成員(屬性、方法、參數(shù)等),裝飾器的執(zhí)行順序由成員類型和所屬(實例/靜態(tài))決定,與源代碼書寫順序無關(guān)。
整體求值順序如下:
- 實例成員:先參數(shù)裝飾器,再方法/訪問器/屬性裝飾器。
對于每個實例成員,按照它們在類中出現(xiàn)的從上到下順序處理。 - 靜態(tài)成員:同樣先參數(shù)裝飾器,再方法/訪問器/屬性裝飾器。
對于每個靜態(tài)成員,按照它們在類中出現(xiàn)的從上到下順序處理。 - 構(gòu)造函數(shù)參數(shù)裝飾器。
- 類裝飾器(最后執(zhí)行)。
可以濃縮成一句話:實例 → 靜態(tài) → 構(gòu)造參數(shù) → 類,每一組內(nèi)部按成員的源代碼順序,且每個成員內(nèi)是參數(shù)裝飾器優(yōu)先于該成員的屬性/方法/訪問器裝飾器。
3. 示例演示
function classDecorator() {
console.log('類裝飾器工廠');
return function (constructor: Function) {
console.log('類裝飾器執(zhí)行');
};
}
function propertyDecorator(name: string) {
console.log(`屬性裝飾器工廠: ${name}`);
return function (target: any, propertyKey: string) {
console.log(`屬性裝飾器執(zhí)行: ${name}`);
};
}
function methodDecorator(name: string) {
console.log(`方法裝飾器工廠: ${name}`);
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
console.log(`方法裝飾器執(zhí)行: ${name}`);
};
}
function parameterDecorator(name: string) {
console.log(`參數(shù)裝飾器工廠: ${name}`);
return function (target: any, propertyKey: string, parameterIndex: number) {
console.log(`參數(shù)裝飾器執(zhí)行: ${name}`);
};
}
@classDecorator()
class Demo {
@propertyDecorator('實例屬性')
instanceProp: string;
@propertyDecorator('靜態(tài)屬性')
static staticProp: string;
constructor(@parameterDecorator('構(gòu)造參數(shù)') param: string) {
this.instanceProp = param;
}
@methodDecorator('實例方法')
instanceMethod(@parameterDecorator('實例方法參數(shù)') arg: number) {}
@methodDecorator('靜態(tài)方法')
static staticMethod(@parameterDecorator('靜態(tài)方法參數(shù)') arg: number) {}
}
運行這段代碼,控制臺輸出順序如下:
屬性裝飾器工廠: 實例屬性
屬性裝飾器執(zhí)行: 實例屬性 // 實例屬性,無參數(shù)裝飾器
方法裝飾器工廠: 實例方法
參數(shù)裝飾器工廠: 實例方法參數(shù)
參數(shù)裝飾器執(zhí)行: 實例方法參數(shù) // 實例方法參數(shù)優(yōu)先
方法裝飾器執(zhí)行: 實例方法 // 實例方法在后屬性裝飾器工廠: 靜態(tài)屬性
屬性裝飾器執(zhí)行: 靜態(tài)屬性 // 靜態(tài)屬性
方法裝飾器工廠: 靜態(tài)方法
參數(shù)裝飾器工廠: 靜態(tài)方法參數(shù)
參數(shù)裝飾器執(zhí)行: 靜態(tài)方法參數(shù) // 靜態(tài)方法參數(shù)優(yōu)先
方法裝飾器執(zhí)行: 靜態(tài)方法 // 靜態(tài)方法在后參數(shù)裝飾器工廠: 構(gòu)造參數(shù)
參數(shù)裝飾器執(zhí)行: 構(gòu)造參數(shù) // 構(gòu)造函數(shù)參數(shù)類裝飾器工廠
類裝飾器執(zhí)行 // 類裝飾器最后
4. 總結(jié)要點
- 同一成員多裝飾器:工廠自上而下求值,裝飾器自下而上執(zhí)行。
- 多成員:先處理實例成員(從上到下),再處理靜態(tài)成員(從上到下),然后構(gòu)造函數(shù)參數(shù),最后類裝飾器。
到此這篇關(guān)于淺談Typescript 裝飾器執(zhí)行順序的文章就介紹到這了,更多相關(guān)Typescript 裝飾器執(zhí)行順序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
論Bootstrap3和Foundation5網(wǎng)格系統(tǒng)的異同
這篇文章主要介紹了Bootstrap3和Foundation5網(wǎng)格系統(tǒng),網(wǎng)格的基本構(gòu)造,如何構(gòu)建的,描述它們的主要部件,以及它們對不同屏幕的大小表現(xiàn)出的差異,感興趣的小伙伴們可以參考一下2016-05-05
Safari 中 filter: blur() 高斯模糊引發(fā)的性能問題及解決方案
在Safari瀏覽器中使用CSS濾鏡如filter:blur()時,可能會遇到性能問題,如頁面卡頓和小方塊現(xiàn)象,這些問題通常與渲染機制和硬件加速的缺失有關(guān),通過開啟硬件加速,如使用transform:translate3d(0,0,0),可以有效解決這些問題,并提升用戶體驗2024-10-10
js中Array.forEach跳出循環(huán)的方法實例
相信大家都知道forEach適用于只是進行集合或數(shù)組遍歷,for則在較復(fù)雜的循環(huán)中效率更高,下面這篇文章主要給大家介紹了關(guān)于js中Array.forEach跳出循環(huán)的相關(guān)資料,需要的朋友可以參考下2021-09-09
ReactHooks+ts(函數(shù)組件)實現(xiàn)原生輪播的示例
這篇文章主要介紹了ReactHooks+ts函數(shù)組件實現(xiàn)原生輪播,在這里下載依賴第一個是js依賴第二個是ts依賴,通過實例代碼介紹了創(chuàng)建tsx文件的方法,需要的朋友可以參考下2022-05-05

