日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

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

新聞中心

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

一、是什么

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

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

是一種在不改變?cè)惡褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展對(duì)象功能

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

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

二、使用方式

由于typescript是一個(gè)實(shí)驗(yàn)性特性,若要使用,需要在tsconfig.json文件啟動(dòng),如下:

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

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

類的裝飾器可以裝飾:

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

例如聲明一個(gè)函數(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 

上述代碼,實(shí)際等同于以下形式:

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

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

方法/屬性裝飾

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

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

可以看到,這三個(gè)屬性實(shí)際就是Object.defineProperty的三個(gè)參數(shù),如果是類的屬性,則沒(méi)有傳遞第三個(gè)參數(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. // 修改實(shí)例方法say 
  33. xmz.say = function() { 
  34.  return 'edit' 

輸出如下圖所示:

參數(shù)裝飾

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

  • target :當(dāng)前對(duì)象的原型
  • 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'); 

輸入如下圖:

訪問(wèn)器裝飾

使用起來(lái)方式與方法裝飾一致,如下:

 
 
 
 
  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ù)一個(gè)函數(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í)行順序

當(dāng)多個(gè)裝飾器應(yīng)用于一個(gè)聲明上,將由上至下依次對(duì)裝飾器表達(dá)式求值,求值的結(jié)果會(huì)被當(dāng)作函數(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)用場(chǎng)景

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

代碼可讀性變強(qiáng)了,裝飾器命名相當(dāng)于一個(gè)注釋

在不改變?cè)写a情況下,對(duì)原來(lái)功能進(jìn)行擴(kuò)展

后面的使用場(chǎng)景中,借助裝飾器的特性,除了提高可讀性之后,針對(duì)已經(jīng)存在的類,可以通過(guò)裝飾器的特性,在不改變?cè)写a情況下,對(duì)原來(lái)功能進(jìn)行擴(kuò)展

參考文獻(xiàn)

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

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


分享名稱:面試官:說(shuō)說(shuō)你對(duì)TypeScript中裝飾器的理解?應(yīng)用場(chǎng)景?
新聞來(lái)源:http://www.5511xx.com/article/dhcpjoe.html