TypeScript: 類的裝飾器(一)

假設(shè)我有一個(gè)汽車工廠拴魄,每天都在生產(chǎn)汽車汛骂,他們都有統(tǒng)一的名字和價(jià)格,都可以在公路上開溯街,那么诱桂,我們很容易寫出如下代碼:

PS: 如果沒有搭建 TypeScript 的開發(fā)環(huán)境,請(qǐng)看這里

class Car {
  private name: string;
  private price: number;

  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }

  getName() {
    console.log(this.name);
  }

  getPrice() {
    console.log(this.price);
  }

  drive() {
    console.log("drive");
  }
}

const toyota: Car = new Car("toyota", 175000);
toyota.getName();
toyota.getPrice();
toyota.drive();

那么呈昔,當(dāng)我需要為每一輛出廠的車都安裝行車記錄儀器時(shí)挥等,那么,我們可能會(huì)修改為如下代碼:

class Car {
  private name: string;
  private price: number;

  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }

  getName() {
    console.log(this.name);
  }

  getPrice() {
    console.log(this.price);
  }

  drive() {
    console.log("drive");
  }
  // 添加行車記錄儀
  driveRecorder() {
    console.log("driveRecorder");
  }
}

const toyota: Car = new Car("toyota", 175000);
toyota.getName();
toyota.getPrice();
toyota.drive();
toyota.driveRecorder();

上面代碼能正確執(zhí)行堤尾,我們也為每輛出廠的車添加上了行車記錄儀肝劲。那么,現(xiàn)實(shí)中行車記錄儀一般都是郭宝,客戶買了車后才會(huì)去安裝的辞槐,也就是說(shuō),車輛在設(shè)計(jì)的時(shí)候不會(huì)考慮把一些非必要的配件都設(shè)計(jì)上粘室,只會(huì)留出空間榄檬,讓客戶去安裝。同理衔统,從代碼的角度 driveRecorder 這個(gè)方法不應(yīng)改寫進(jìn) Car 類里邊鹿榜,它不是在類本身的東西先朦,是之后加上的,上面的代碼顯然破壞了類的設(shè)計(jì)犬缨,那么我們可以把 driveRecorder 添加到類的外面喳魏,也就是把它做成一個(gè)裝飾器,裝飾我們的類怀薛,那么我們的代碼修改為如下:

function recorder(constructor: any) {
  constructor.prototype.driveRecorder = () => {
    console.log("driveRecorder");
  };
}

@recorder // @recorder 為類的裝飾器
class Car {
  private name: string;
  private price: number;

  constructor(name: string, price: number) {
    this.name = name;
    this.price = price;
  }

  getName() {
    console.log(this.name);
  }

  getPrice() {
    console.log(this.price);
  }

  drive() {
    console.log("drive");
  }
}

const toyota: Car = new Car("toyota", 175000);
toyota.getName();
toyota.getPrice();
toyota.drive();
toyota.driveRecorder();

那么刺彩,如果您直接抄上面的代碼,可能會(huì)得到如下兩個(gè)報(bào)錯(cuò)提示:

1.裝飾器語(yǔ)法報(bào)錯(cuò)

通過提示我們知道枝恋,TypeScript的裝飾器在ES語(yǔ)法中屬于一個(gè)實(shí)驗(yàn)性值的語(yǔ)法创倔,故在VSCode中會(huì)報(bào)錯(cuò),如果要使用裝飾器
則需要把tsconfig.json的'experimentalDecorators'的注釋打開才能解除警報(bào)焚碌,如下圖


2.實(shí)例調(diào)用裝飾器方法報(bào)錯(cuò)

關(guān)于這個(gè)錯(cuò)誤畦攘,我們看下裝飾器

function recorder(constructor: any) {
  constructor.prototype.driveRecorder = () => {
    console.log("driveRecorder");
  };
}

在 TypeScript 的類裝飾器中,裝飾器是一個(gè)函數(shù)十电,那么它的參數(shù)就是這個(gè)類知押,這里的 constructor 就是我們傳入的 Car 類,我們用原型的方法把 driveRecorder 掛載到 constructor 而 constructor 的類型聲明為 any鹃骂,toyota 的類型為 Car台盯,兩個(gè)類型不一樣,所以找不該 driveRecorder 方法報(bào)錯(cuò)畏线,這里我們就臨時(shí)改一下調(diào)用的方式(把 toyota 的類型臨時(shí)改成any):

(toyota as any).driveRecorder();

那么報(bào)錯(cuò)沒了静盅,我們運(yùn)行下代碼,結(jié)果是對(duì)的

回過頭來(lái)看裝飾器和原來(lái)在類中的修改寝殴,執(zhí)行的結(jié)果是一樣的蒿叠,但編程的思想?yún)s不一樣,直接在類中修改看似很方便蚣常,也是我們最容易想到的一個(gè)方式市咽,但這只是我們?cè)谧钍孢m的環(huán)境下想到的,有可能史隆,這個(gè)類不是我們寫魂务,是別人寫的,那么非常不推薦大家去修改別人的代碼泌射,這里推薦使用裝飾器,直接在別人寫好的類上面加上鬓照,不會(huì)破壞別人的代碼
原文鏈接

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末熔酷,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子豺裆,更是在濱河造成了極大的恐慌拒秘,老刑警劉巖号显,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異躺酒,居然都是意外死亡押蚤,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門羹应,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)揽碘,“玉大人,你說(shuō)我怎么就攤上這事园匹■ù蹋” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵裸违,是天一觀的道長(zhǎng)掖桦。 經(jīng)常有香客問我,道長(zhǎng)供汛,這世上最難降的妖魔是什么枪汪? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮怔昨,結(jié)果婚禮上料饥,老公的妹妹穿的比我還像新娘。我一直安慰自己朱监,他們只是感情好岸啡,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著赫编,像睡著了一般巡蘸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上擂送,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天悦荒,我揣著相機(jī)與錄音,去河邊找鬼嘹吨。 笑死搬味,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蟀拷。 我是一名探鬼主播碰纬,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼问芬!你這毒婦竟也來(lái)了悦析?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤此衅,失蹤者是張志新(化名)和其女友劉穎强戴,沒想到半個(gè)月后亭螟,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡骑歹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年预烙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片道媚。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡扁掸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出衰琐,到底是詐尸還是另有隱情也糊,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布羡宙,位于F島的核電站狸剃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏狗热。R本人自食惡果不足惜钞馁,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望匿刮。 院中可真熱鬧僧凰,春花似錦、人聲如沸熟丸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)光羞。三九已至绩鸣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間纱兑,已是汗流浹背呀闻。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留潜慎,地道東北人捡多。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像铐炫,于是被迫代替她去往敵國(guó)和親垒手。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345