溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

TypeScript中Enum怎么用

發(fā)布時(shí)間:2021-07-05 13:45:02 來(lái)源:億速云 閱讀:139 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要為大家展示了“TypeScript中Enum怎么用”,內(nèi)容簡(jiǎn)而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“TypeScript中Enum怎么用”這篇文章吧。

Enum

Enum 是在 TypeScript 中新增的語(yǔ)法,也叫做枚舉,一般用它來(lái)管理多個(gè)相同系列的常量(即不能被修改的變量),用于狀態(tài)的判斷。

在 Web 中比較常見(jiàn)的狀態(tài)判斷,是在處理請(qǐng)求時(shí),要針對(duì)不同的響應(yīng)狀態(tài)碼做對(duì)應(yīng)的處理:

const handleResponseStatus = (status: number): void => {
  switch (status) {
    case 200: // 請(qǐng)求成功時(shí)
      // Do something...
      break;
    case 400: // 請(qǐng)求失敗時(shí)
      // Do something...
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

但因?yàn)轫憫?yīng)狀態(tài)碼都是預(yù)先定義好的,所以沒(méi)什么爭(zhēng)議,代碼寫(xiě)成這樣看也很正常,但是如果后端在服務(wù)器發(fā)生錯(cuò)誤時(shí)自定義了一些編碼,并告訴前端,這些代碼都代表什么錯(cuò)誤,那么上面的函數(shù)可能會(huì)變成這樣:

const handleWrongStatus = (status: string): void => {
  switch (status) {
    case 'A':
      // Do something...
      break;
    case 'B':
      // Do something...
      break;
    case 'C':
      // Do something...
      break;
    default:
      throw (new Error('No have wrong code!'));
  }
};

如果是這種代碼,別說(shuō)是剛接手的人,就算是你自己兩星期前寫(xiě)的,恐怕不去翻文檔也想不起它們都代表什么了吧。

但是如果善用 Enum ,就可以避免上述發(fā)生的情況。

基本用法

先來(lái)看看 Enum 該怎么定義,它和 Object 的用法很像:

enum requestStatusCodes {
  error,
  success,
}

不需要在內(nèi)容與名稱(chēng)之間加等號(hào),直接在大括號(hào)內(nèi)敘述該 Enum 中具有哪些變量,與其說(shuō)是變量,不如說(shuō)是常量更恰當(dāng)些,因?yàn)樵?Enum 中的值是不可修改的,所以也不必?fù)?dān)心這些定義好的規(guī)則會(huì)在代碼執(zhí)行的過(guò)程中發(fā)生改變,導(dǎo)致執(zhí)行錯(cuò)誤。

而既然 Enum 是用來(lái)定義同一個(gè)系列常量的,那這些常量應(yīng)該都能維護(hù)特定的值。沒(méi)錯(cuò),在 Enum 中的每個(gè)常量,都可以通過(guò) = 來(lái)指定具體的值 。

但如果是像前面的 requestStatusCodes ,沒(méi)有為 errorsuccess 指定具體的值也不會(huì)出錯(cuò),因?yàn)?TypeScript 會(huì)從 0 開(kāi)始自動(dòng)遞增定義值,所以簽名的 requestStatusCodes 會(huì)和下面的結(jié)果相同:

enum requestStatusCodes {
  error = 0,
  success = 1,
}console.log(requestStatusCodes.error) // 0
console.log(requestStatusCodes.success) // 1

除了數(shù)字外,也可以定義為字串:

enum requestWrongCodes {
  missingParameter = 'A',
  wrongParameter = 'B',
  invalidToken = 'C',
}console.log(requestWrongCodes.wrongParameter) // 'B'

當(dāng)然也可以在一個(gè) enum 中設(shè)定不同的類(lèi)型,但這樣一點(diǎn)意義都沒(méi)有:

enum requestStatusCodes {
  error = 0,
  success = 'OK',
}

了解基本的 Enum 怎么定義后,接著就來(lái)改寫(xiě)前面代碼中的 handleResponseStatushandleWrongStatus ,讓它們?cè)谡Z(yǔ)義上能夠更明確。

首先用 Enum 定義兩者的狀態(tài)描述:

enum requestStatusCodes {
  error = 400,
  success = 200,
}

enum requestWrongCodes {
  missingParameter = 'A',
  wrongParameterType = 'B',
  invalidToken = 'C',
}

然后修改 handleResponseStatushandleWrongStatus 中的 Switch 判斷:

const handleResponseStatus = (status: number): void => {
  switch (status) {
    case requestStatusCodes.success:
      // Do something...
      break;
    case requestStatusCodes.error:
      // Do something...
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

const handleWrongStatus = (status: string): void => {
  // 如果覺(jué)得 requestWrongCodes.missingParameter 太長(zhǎng)了,也可以用以下方式:
  const { missingParameter, wrongParameterType, invalidToken, } = requestWrongCodes;
  switch (status) {
    case missingParameter:
      // Do something...
      break;
    case wrongParameterType:
      // Do something...
      break;
    case invalidToken:
      // Do something...
      break;
    default:
      throw (new Error('No have wrong code!'));
  }
};

修改后的代碼就變得直觀多了,因?yàn)闋顟B(tài)碼都被放到了 Enum 中統(tǒng)一管理,所以就能用常量名來(lái)代表它們,之后不管過(guò)了多久,可以明確的知道這里再做什么,甚至連注解或文檔都不用寫(xiě)了,因?yàn)榇a就是最好的文檔。

善用 Enum 能使代碼絕對(duì)是不可或缺的,但就算沒(méi)使用 TypeScript 也別灰心,因?yàn)?TypeScript 最終會(huì)被轉(zhuǎn)換為 JavaScript ,那來(lái)看看如何直接用 JavaScript 實(shí)現(xiàn) Enum 吧!

用原生 JavaScript 實(shí)現(xiàn) Enum

在前面說(shuō)過(guò) Enum 很像 Object ,如果研究一下 Enum 被編譯成 javascript 之后的代碼,就會(huì)發(fā)現(xiàn)還真的是 Object。

Enum 被編譯后會(huì)變成 Key 和 Value 反向?qū)?yīng)的對(duì)象,這樣看起來(lái)非常簡(jiǎn)單,為了方便使用,下面把它的編譯方式寫(xiě)成一個(gè)函數(shù):

const newEnum = (descriptions) => {
  const result = {};
  Object.keys(descriptions).forEach((description) => {
    result[result[description] = descriptions[description]] = description;
  });
  return result;
};

const responseStatus = newEnum({
  error: 400,
  success: 200,
});

// { '200': 'success', '400': 'error', error: 400, success: 200 }
console.log(responseStatus);

雖然得到的結(jié)果相同,但是喪失了 Enum 中最可貴的常量特色,如果不能讓它變成不可修改,那就有可能會(huì)在代碼里不經(jīng)意地改動(dòng)它,導(dǎo)致執(zhí)行結(jié)果可能出錯(cuò),于是可以在最后利用 Object.freeze() ,讓外部操作無(wú)法新增、刪除或重新定義任何 Property :

const newEnum = (descriptions) => {
  const result = {};
  Object.keys(descriptions).forEach((description) => {
    result[result[description] = descriptions[description]] = description;
  });
  return Object.freeze(result);
};

const responseStatus = newEnum({
  error: 400,
  success: 200,
});

// 即使不小心修改了
responseStatus['200'] = 'aaaaaaaa';

// 仍然是 { '200': 'success', '400': 'error', error: 400, success: 200 }
console.log(responseStatus);

這樣就能簡(jiǎn)單在 JavaScript 中實(shí)現(xiàn) Enum 了。

const Enum 的用法

從前面的 JavaScript 代碼中可以看到 Enum 編譯過(guò)后會(huì)變成 Key 和 Value 互相對(duì)應(yīng)的 Object ,也就是說(shuō)不管是用 Key 還是Value 都可以取出對(duì)應(yīng)的值,

但是如果用 const 聲明 Enum ,編譯之后就不會(huì)產(chǎn)生 Object。

直接看例子,假設(shè)我把 responseStateconst 重新生命,且也是以 handleResponseStatus 使用該 Enum 做判斷:

enum responseStatus {
  error = 400,
  success = 200,
}

const handleResponseStatus = (status: number): void => {
  switch (status) {
    case responseStatus.success:
      console.log('請(qǐng)求成功!');
      break;
    case responseStatus.error:
      console.log('請(qǐng)求失敗!');
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

看起來(lái)一切正常,不過(guò)在編譯后的 JavaScript 中,會(huì)發(fā)現(xiàn) Enum 并沒(méi)有產(chǎn)生 Object ,而是直接用 const 聲明在 Enum 中的值。

const 聲明 Enum 有幾個(gè)好處:

  • 假設(shè)要用到的 Enum 非常多,那在執(zhí)行時(shí)就會(huì)不停地使用 IIFE 產(chǎn)生 Object 將 Key 和 Value 綁定到 Object,會(huì)造成一些效率上的損失,也會(huì)增加內(nèi)存,但是 const 并不會(huì)產(chǎn)生 Object ,也就不會(huì)有以上的問(wèn)題。

  • 就算到的 Enum 不多,判斷時(shí)也需要一直從 Object 中找出對(duì)應(yīng)的值,而如果是用 const 聲明 Enum ,在編譯成 JS 時(shí)就將聲明的值直接放入判斷中。

不過(guò)這樣也就沒(méi)法從 Enum 中反向取值了,因?yàn)樗⒉粫?huì)產(chǎn)生對(duì)象:

const enum responseStatus {
  error = 400,
  success = 200,
}// 會(huì)出錯(cuò),因?yàn)橐呀?jīng)沒(méi)有對(duì)象可供查找了
console.log(responseStatus[400])// 但這個(gè)不會(huì)有問(wèn)題,因?yàn)榫幾g的時(shí)候會(huì)直接填值
console.log(responseStatus.error)// 編譯后:
// console.log(400)

以上是“TypeScript中Enum怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI