(Decorators)是一種特殊類型的聲明,它可以被附加到類聲明,方法,屬性或參數(shù)上征候。
裝飾器由@符號緊接一個函數(shù)名稱,如@expression,expression求值后必須是一個函數(shù),
在函數(shù)執(zhí)行的時(shí)候裝飾器的聲明方法會被執(zhí)行味咳。
裝飾器是用來給附著的主體進(jìn)行裝飾,添加額外行為的。
感覺typescript的裝飾器就是Java的注解,'C#'的特性,算是一種元編程,
定義在對象上,用于代碼執(zhí)行前后,做額外的事情,主要提供面向截面編程陷舅。
TypeScript官方介紹:
裝飾器(Decorators)為我們在類的聲明及成員上通過元編程語法添加標(biāo)注提供了一種方式。
Javascript里的裝飾器目前處在建議征集的第一階段,但在TypeScript里已做為一項(xiàng)實(shí)驗(yàn)性特性予以支持审洞。
注意:裝飾器是一項(xiàng)實(shí)驗(yàn)性特性,在未來的版本中可能會發(fā)生改變莱睁。
若要啟用實(shí)驗(yàn)性的裝飾器特性,你必須在命令行或tsconfig.json里啟用experimentalDecorators編譯器
選項(xiàng):
命令行: tsc --target ES5 --experimentalDecorators
tsconfig.json文件啟用:
{
"compilerOptions": {
"target": "ES5",
"experimentalDecorators": true
}
}
裝飾器求值:
類中不同聲明的裝飾器將按以下規(guī)定的順序應(yīng)用:
1.參數(shù)裝飾器,然后依次是方法裝飾器,訪問符裝飾器,或?qū)傩匝b飾器應(yīng)用到每個實(shí)例成員。
2.參數(shù)裝飾器,然后依次是方法裝飾器,訪問符裝飾器,或?qū)傩匝b飾其應(yīng)用到每個靜態(tài)成員芒澜。
3.參數(shù)裝飾器應(yīng)用到構(gòu)造函數(shù)仰剿。
4.類裝飾器應(yīng)用到類。
類裝飾器:
1.在類聲明之前聲明,類裝飾器應(yīng)用于類的構(gòu)造函數(shù),可以用來監(jiān)視,修改或替換類定義痴晦。
重點(diǎn)1:類裝飾器表達(dá)式會在運(yùn)行時(shí)當(dāng)做函數(shù)被調(diào)用,類的構(gòu)造函數(shù)被當(dāng)做其唯一的參數(shù)南吮。
重點(diǎn)2:如果類裝飾器返回一個值,它會使用提供的構(gòu)造函數(shù)來替換類的聲明。
(也就是說,可以用類裝飾器返回一個函數(shù)的形式來動態(tài)替換類的原本構(gòu)造函數(shù))誊酌。
注意: 如:
@sealed
class Greeter{
greeter:string;
constructor(message:string){
this.greeter=message;
}
greeter(){
return "hello"+this.greeter;
}
}
//@sealed裝飾器定義如下
function sealed(constructor:Function){
Object.seal(constructor);
Object.seal(constructor.protected);
//當(dāng)@sealed被執(zhí)行時(shí)它將密封該了類的構(gòu)造函數(shù)和原型部凑。
}
方法裝飾器:
聲明在一個方法的聲明之前,它會被用到方法的屬性描述符上(descriptor),
可以用來監(jiān)視,修改或替換方法定義。
方法裝飾器不能用在聲明文件(.d.ts), 重載或者任何外部上下(比如declare的類中)中碧浊。
方法裝飾器表達(dá)式會在運(yùn)行時(shí)當(dāng)作函數(shù)被調(diào)用,傳入下列3個參數(shù):
1.target:對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實(shí)例成員是類的原型對象涂邀。
2.propertyKey:方法(成員)的名稱。
3.descriptor:成員的屬性描述符箱锐。
注意:
如果代碼的輸出版本小于ES5,屬性描述符將會是undefined必孤。
如果方法裝飾器的返回一個值,它會被用作方法的屬性描述符,如果代碼的輸出目標(biāo)小于ES5,
返回值會被忽略。
其中descriptor類型為TypedPropertyDescriptor, 在typescript中定義如下:
interface TYpedPropertyDescriptor {
enumerable?:boolean; //是否可遍歷
configurable?:boolean; //屬性描述是否可改變或者屬性是否可刪除
writable?:boolean; //是否可修改
value?:T; //屬性的值
get?:()=>T; //屬性的訪問器函數(shù)(getter)
set?:(value:T)=>void //屬性的設(shè)置器函數(shù)
}
如:
class TestClass{
@log
testMethod(arg:string){
return "xzm:"+arg;
}
}
//裝飾器@log的實(shí)現(xiàn):
function log(
target:Object,
properrtyKey:string,
descriptor:TypedPropertyDescriptor
){
let origin=descriptor.value; //通過方法屬性描述符的value屬性,取得有關(guān)方法對象
descriptor.value=function(...args:any[]){
console.log("args:"+JSON.stringify(args)); //調(diào)用前
let result=origin.apply(this,args); //調(diào)用方法
console.log("The result" + result);
return result;
}
return descriptor;
}
//使用代碼測試:
new TestClass().testMethod("test method descorator");
//結(jié)果輸出如下:
//agrs:["test method descorator"]
//The result-xzm:test method descorator
訪問器裝飾器:
訪問器裝飾器聲明在一個訪問器聲明之前瑞躺。
訪問器裝飾器應(yīng)用于訪問器的屬性描述符(),并且可以用來監(jiān)視,修改或替換一個訪問器定義敷搪。
注意:
TypeScript不允許同時(shí)裝飾一個成員的set或者get訪問器。
取而代之的是,一個成員的所有裝飾必須應(yīng)用在文檔順序的第一個訪問器上幢哨。
這是因?yàn)? 在裝飾器應(yīng)用于一個屬性描述符時(shí),它聯(lián)合了get和set訪問器,而不是分開聲明的赡勘。
訪問器裝飾器表達(dá)式會在運(yùn)行時(shí)當(dāng)做函數(shù)被調(diào)用,傳入下列3個參數(shù):
1.target:對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實(shí)例成員是類的原型對象。
2.properrtyKey:方法(成員)的名稱捞镰。
3.descriptor:成員的屬性描述符闸与。 訪問器裝飾器基本和方法裝飾器一樣,
除了需要注意上面提到的不允許同時(shí)裝飾一個成員的set和get訪問器以外毙替。
屬性裝飾器:
屬性裝飾器聲明在一個屬性聲明之前,屬性裝飾器表達(dá)式會在運(yùn)行時(shí)當(dāng)做函數(shù)被調(diào)用,傳入下列兩個參數(shù):
1.target:對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實(shí)例成員是類的原型對象。
2.property:成員(屬性)的名字践樱。
注意:屬性描述符不會作為參數(shù)傳入屬性裝飾器,這于TypeScript是如何初始化屬性裝飾器有關(guān)厂画。
因?yàn)槟壳皼]有辦法在頂一個原型對象的成員時(shí)描述一個實(shí)例的屬性, 并且沒辦法監(jiān)視或修改一個屬性的
初始化方法。因此屬性描述符只能用來監(jiān)視類中是否聲明了某個名字的屬性拷邢。
參數(shù)裝飾器:
聲明在一個參數(shù)聲明之前(用于的類的構(gòu)造函數(shù)或方法聲明),參數(shù)裝飾器表達(dá)式會在運(yùn)行是被當(dāng)做函數(shù)調(diào)用
1.target:對于靜態(tài)成員來說是類的構(gòu)造函數(shù),對于實(shí)例成員是類的原型對象袱院。
2.propertyKey:成員的名字。
3.parameterIndex:參數(shù)在函數(shù)參數(shù)列表中的索引瞭稼。 注意:參數(shù)裝飾器只能用來監(jiān)視一個方法的參數(shù)
是否被傳入忽洛。
參數(shù)裝飾器在Angular中被廣泛使用,特別是結(jié)合reflect-metadata庫來支持實(shí)驗(yàn)性的Metadata
API。
參數(shù)裝飾器的返回值會被忽略环肘。
裝飾器組合:
TypeScript支持多個裝飾器同時(shí)應(yīng)用到一個聲明上,實(shí)現(xiàn)多個裝飾器復(fù)合使用,語法支持從左到右,
或從上到下書寫欲虚。
在TypeScript里,當(dāng)多個裝飾器應(yīng)用在一個聲明上的時(shí)候,會進(jìn)行如下步驟的操作:
1.從左到右(從上到下)依次執(zhí)行裝飾器函數(shù),得到返回結(jié)果。
2.返回的結(jié)果會被當(dāng)做函數(shù),從左到右(從上倒下)依次調(diào)用悔雹。
裝飾器
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
- 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來臼隔,“玉大人嘹裂,你說我怎么就攤上這事∷の眨” “怎么了寄狼?”我有些...
- 文/不壞的土叔 我叫張陵,是天一觀的道長氨淌。 經(jīng)常有香客問我泊愧,道長,這世上最難降的妖魔是什么盛正? 我笑而不...
- 正文 為了忘掉前任删咱,我火速辦了婚禮,結(jié)果婚禮上豪筝,老公的妹妹穿的比我還像新娘痰滋。我一直安慰自己摘能,他們只是感情好,可當(dāng)我...
- 文/花漫 我一把揭開白布敲街。 她就那樣靜靜地躺著团搞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪多艇。 梳的紋絲不亂的頭發(fā)上逻恐,一...
- 文/蒼蘭香墨 我猛地睜開眼阵面,長吁一口氣:“原來是場噩夢啊……” “哼轻局!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起样刷,我...
- 序言:老撾萬榮一對情侶失蹤仑扑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后置鼻,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體镇饮,經(jīng)...
- 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
- 正文 我和宋清朗相戀三年箕母,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了储藐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
- 正文 年R本政府宣布,位于F島的核電站希太,受9級特大地震影響克饶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜誊辉,卻給世界環(huán)境...
- 文/蒙蒙 一彤路、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芥映,春花似錦洲尊、人聲如沸远豺。這莊子的主人今日做“春日...
- 文/蒼蘭香墨 我抬頭看了看天上的太陽躯护。三九已至,卻和暖如春丽涩,著一層夾襖步出監(jiān)牢的瞬間棺滞,已是汗流浹背。 一陣腳步聲響...
- 正文 我出身青樓矮男,卻偏偏與公主長得像移必,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子毡鉴,可洞房花燭夜當(dāng)晚...