日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
面試官:說說你對TypeScript中裝飾器的理解?應(yīng)用場景?

一、是什么

裝飾器是一種特殊類型的聲明,它能夠被附加到類聲明,方法, 訪問符,屬性或參數(shù)上

成都創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計、成都網(wǎng)站制作、鄉(xiāng)寧網(wǎng)絡(luò)推廣、小程序設(shè)計、鄉(xiāng)寧網(wǎng)絡(luò)營銷、鄉(xiāng)寧企業(yè)策劃、鄉(xiāng)寧品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供鄉(xiāng)寧建站搭建服務(wù),24小時服務(wù)熱線:028-86922220,官方網(wǎng)址:www.cdcxhl.com

是一種在不改變原類和使用繼承的情況下,動態(tài)地擴展對象功能

同樣的,本質(zhì)也不是什么高大上的結(jié)構(gòu),就是一個普通的函數(shù),@expression 的形式其實是Object.defineProperty的語法糖

expression求值后必須也是一個函數(shù),它會在運行時被調(diào)用,被裝飾的聲明信息做為參數(shù)傳入

二、使用方式

由于typescript是一個實驗性特性,若要使用,需要在tsconfig.json文件啟動,如下:

 
 
 
 
  1.     "compilerOptions": { 
  2.         "target": "ES5", 
  3.         "experimentalDecorators": true 
  4.     } 

typescript裝飾器的使用和javascript基本一致

類的裝飾器可以裝飾:

  • 方法/屬性
  • 參數(shù)
  • 訪問器
  • 類裝飾

例如聲明一個函數(shù) addAge 去給 Class 的屬性 age 添加年齡.

 
 
 
 
  1. function addAge(constructor: Function) { 
  2.   constructor.prototype.age = 18; 
  3.  
  4. @addAge 
  5. class Person{ 
  6.   name: string; 
  7.   age!: number; 
  8.   constructor() { 
  9.     this.name = 'huihui'; 
  10.   } 
  11.  
  12. let person = new Person(); 
  13.  
  14. console.log(person.age); // 18 

上述代碼,實際等同于以下形式:

 
 
 
 
  1. Person = addAge(function Person() { ... }); 

上述可以看到,當裝飾器作為修飾類的時候,會把構(gòu)造器傳遞進去。constructor.prototype.age 就是在每一個實例化對象上面添加一個 age 屬性

方法/屬性裝飾

同樣,裝飾器可以用于修飾類的方法,這時候裝飾器函數(shù)接收的參數(shù)變成了:

  • target:對象的原型
  • propertyKey:方法的名稱
  • descriptor:方法的屬性描述符

可以看到,這三個屬性實際就是Object.defineProperty的三個參數(shù),如果是類的屬性,則沒有傳遞第三個參數(shù)

如下例子:

 
 
 
 
  1. // 聲明裝飾器修飾方法/屬性 
  2. function method(target: any, propertyKey: string, descriptor: PropertyDescriptor) { 
  3.   console.log(target); 
  4.   console.log("prop " + propertyKey); 
  5.   console.log("desc " + JSON.stringify(descriptor) + "\n\n"); 
  6.   descriptor.writable = false; 
  7. }; 
  8.  
  9. function property(target: any, propertyKey: string) { 
  10.   console.log("target", target) 
  11.   console.log("propertyKey", propertyKey) 
  12.  
  13. class Person{ 
  14.  @property 
  15.  name: string; 
  16.  constructor() { 
  17.    this.name = 'huihui'; 
  18.  } 
  19.  
  20.  @method 
  21.  say(){ 
  22.    return 'instance method'; 
  23.  } 
  24.  
  25.  @method 
  26.  static run(){ 
  27.    return 'static method'; 
  28.  } 
  29.  
  30. const xmz = new Person(); 
  31.  
  32. // 修改實例方法say 
  33. xmz.say = function() { 
  34.  return 'edit' 

輸出如下圖所示:

參數(shù)裝飾

接收3個參數(shù),分別是:

  • target :當前對象的原型
  • propertyKey :參數(shù)的名稱
  • index:參數(shù)數(shù)組中的位置
 
 
 
 
  1. function logParameter(target: Object, propertyName: string, index: number) { 
  2.   console.log(target); 
  3.   console.log(propertyName); 
  4.   console.log(index); 
  5.  
  6. class Employee { 
  7.   greet(@logParameter message: string): string { 
  8.       return `hello ${message}`; 
  9.   } 
  10. const emp = new Employee(); 
  11. emp.greet('hello'); 

輸入如下圖:

訪問器裝飾

使用起來方式與方法裝飾一致,如下:

 
 
 
 
  1. function modification(target: Object, propertyKey: string, descriptor: PropertyDescriptor) { 
  2.   console.log(target); 
  3.   console.log("prop " + propertyKey); 
  4.   console.log("desc " + JSON.stringify(descriptor) + "\n\n"); 
  5. }; 
  6.  
  7. class Person{ 
  8.  _name: string; 
  9.  constructor() { 
  10.    this._name = 'huihui'; 
  11.  } 
  12.  
  13.  @modification 
  14.  get name() { 
  15.    return this._name 
  16.  } 

裝飾器工廠

如果想要傳遞參數(shù),使裝飾器變成類似工廠函數(shù),只需要在裝飾器函數(shù)內(nèi)部再函數(shù)一個函數(shù)即可,如下:

 
 
 
 
  1. function addAge(age: number) { 
  2.   return function(constructor: Function) { 
  3.     constructor.prototype.age = age 
  4.   } 
  5.  
  6. @addAge(10) 
  7. class Person{ 
  8.   name: string; 
  9.   age!: number; 
  10.   constructor() { 
  11.     this.name = 'huihui'; 
  12.   } 
  13.  
  14. let person = new Person(); 

執(zhí)行順序

當多個裝飾器應(yīng)用于一個聲明上,將由上至下依次對裝飾器表達式求值,求值的結(jié)果會被當作函數(shù),由下至上依次調(diào)用,例如如下:

 
 
 
 
  1. function f() { 
  2.     console.log("f(): evaluated"); 
  3.     return function (target, propertyKey: string, descriptor: PropertyDescriptor) { 
  4.         console.log("f(): called"); 
  5.     } 
  6.  
  7. function g() { 
  8.     console.log("g(): evaluated"); 
  9.     return function (target, propertyKey: string, descriptor: PropertyDescriptor) { 
  10.         console.log("g(): called"); 
  11.     } 
  12.  
  13. class C { 
  14.     @f() 
  15.     @g() 
  16.     method() {} 
  17.  
  18. // 輸出 
  19. f(): evaluated 
  20. g(): evaluated 
  21. g(): called 
  22. f(): called 

三、應(yīng)用場景

可以看到,使用裝飾器存在兩個顯著的優(yōu)點:

代碼可讀性變強了,裝飾器命名相當于一個注釋

在不改變原有代碼情況下,對原來功能進行擴展

后面的使用場景中,借助裝飾器的特性,除了提高可讀性之后,針對已經(jīng)存在的類,可以通過裝飾器的特性,在不改變原有代碼情況下,對原來功能進行擴展

參考文獻

https://www.tslang.cn/docs/handbook/decorators.html

https://juejin.cn/post/6844903876605280269#heading-5


名稱欄目:面試官:說說你對TypeScript中裝飾器的理解?應(yīng)用場景?
分享地址:http://www.dlmjj.cn/article/dhcpjoe.html