標題裝飾器定義 類裝飾器 屬性裝飾器 裝飾器工廠 方法裝飾器 方法參數裝飾器 裝飾器的執行順序
裝飾器:裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法,屬性或參數上,可以修改類的行爲。
通俗的講裝飾器就是一個方法,可以注入到類、方法、屬性參數上來擴展類、屬性、方法、參數的功能。
常見的裝飾器有:類裝飾器、屬性裝飾器、方法裝飾器、參數裝飾器
裝飾器的寫法:普通裝飾器(無法傳參) 、 裝飾器工廠(可傳參)
裝飾器是過去幾年中js最大的成就之一,已是Es7的標準特性之一
1、類裝飾器:類裝飾器在類聲明之前被聲明(緊靠着類聲明)。 類裝飾器應用於類構造函數,可以用來監視,修改或替換類定義。 傳入一個參數
1.1 類裝飾器:普通裝飾器(無法傳參)
function logClass(params:any){
console.log(params);
// params 就是當前類
params.prototype.apiUrl='動態擴展的屬性';
params.prototype.run=function(){
console.log('我是一個run方法');
}
}
@logClass
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
1.2 類裝飾器:裝飾器工廠(可傳參)
function logClass(params:string){
return function(target:any){
console.log(target);
console.log(params);
target.prototype.apiUrl=params;
}
}
@logClass('http://www.itying.com/api')
class HttpClient{
constructor(){
}
getData(){
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
1、類裝飾器
下面是一個重載構造函數的例子。
類裝飾器表達式會在運行時當作函數被調用,類的構造函數作爲其唯一的參數。
如果類裝飾器返回一個值,它會使用提供的構造函數來替換類的聲明。
function logClass(target:any){
console.log(target);
return class extends target{
apiUrl:any='我是修改後的數據';
getData(){
this.apiUrl=this.apiUrl+'----';
console.log(this.apiUrl);
}
}
}
@logClass
class HttpClient{
public apiUrl:string | undefined;
constructor(){
this.apiUrl='我是構造函數裏面的apiUrl';
}
getData(){
console.log(this.apiUrl);
}
}
var http=new HttpClient();
http.getData();
2、屬性裝飾器
屬性裝飾器表達式會在運行時當作函數被調用,傳入下列2個參數:
1、對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象。
2、成員的名字。
//類裝飾器
function logClass(params:string){
return function(target:any){
// console.log(target);
// console.log(params);
}
}
//屬性裝飾器
function logProperty(params:any){
return function(target:any,attr:any){
console.log(target);
console.log(attr);
target[attr]=params;
}
}
@logClass('xxxx')
class HttpClient{
@logProperty('http://itying.com')
public url:any |undefined;
constructor(){
}
getData(){
console.log(this.url);
}
}
var http=new HttpClient();
http.getData();
3、方法裝飾器
它會被應用到方法的 屬性描述符上,可以用來監視,修改或者替換方法定義。
方法裝飾會在運行時傳入下列3個參數:
1、對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象。
2、成員的名字。
3、成員的屬性描述符。
方法裝飾器一
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc);
target.apiUrl='xxxx';
target.run=function(){
console.log('run');
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(){
console.log(this.url);
}
}
var http:any=new HttpClient();
console.log(http.apiUrl);
http.run();
方法裝飾器二
function get(params:any){
return function(target:any,methodName:any,desc:any){
console.log(target);
console.log(methodName);
console.log(desc.value);
//修改裝飾器的方法 把裝飾器方法裏面傳入的所有參數改爲string類型
//1、保存當前的方法
var oMethod=desc.value;
desc.value=function(...args:any[]){
args=args.map((value)=>{
return String(value);
})
oMethod.apply(this,args);
}
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
@get('http://www.itying,com')
getData(...args:any[]){
console.log(args);
console.log('我是getData裏面的方法');
}
}
var http=new HttpClient();
http.getData(123,'xxx');
4、方法參數裝飾器
參數裝飾器表達式會在運行時當作函數被調用,可以使用參數裝飾器爲類的原型增加一些元素數據 ,傳入 下列3個參數:
1、對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象。
2、方法的名字。
3、參數在函數參數列表中的索引。
function logParams(params:any){
return function(target:any,methodName:any,paramsIndex:any){
console.log(params);
console.log(target);
console.log(methodName);
console.log(paramsIndex);
target.apiUrl=params;
}
}
class HttpClient{
public url:any |undefined;
constructor(){
}
getData(@logParams('xxxxx') uuid:any){
console.log(uuid);
}
}
var http:any = new HttpClient();
http.getData(123456);
console.log( http.apiUrl);
裝飾器執行順序
屬性》方法》方法參數》類
如果有多個同樣的裝飾器,它會先執行後面的
function logClass1(params:string){
return function(target:any){
console.log('類裝飾器1')
}
}
function logClass2(params:string){
return function(target:any){
console.log('類裝飾器2')
}
}
function logAttribute1(params?:string){
return function(target:any,attrName:any){
console.log('屬性裝飾器1')
}
}
function logAttribute2(params?:string){
return function(target:any,attrName:any){
console.log('屬性裝飾器2')
}
}
function logMethod1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法裝飾器1')
}
}
function logMethod2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法裝飾器2')
}
}
function logParams1(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法參數裝飾器1')
}
}
function logParams2(params?:string){
return function(target:any,attrName:any,desc:any){
console.log('方法參數裝飾器2')
}
}
@logClass1('http://www.itying.com/api')
@logClass2('xxxx')
class HttpClient{
@logAttribute1()
@logAttribute2()
public apiUrl:string | undefined;
constructor(){
}
@logMethod1()
@logMethod2()
getData(){
return true;
}
setData(@logParams1() attr1:any,@logParams2() attr2:any,){
}
}
var http:any=new HttpClient();