Maison  >  Article  >  interface Web  >  Parlons de l'utilisation d'Enum (énumération) dans TypeScript

Parlons de l'utilisation d'Enum (énumération) dans TypeScript

青灯夜游
青灯夜游avant
2021-07-05 10:19:213344parcourir

Cet article vous présentera la syntaxe Enum (énumération) dans TypeScript, parlera de l'utilisation de base d'Enum et comment utiliser JavaScript natif pour implémenter Enum.

Parlons de l'utilisation d'Enum (énumération) dans TypeScript

Enum

Enum est une nouvelle syntaxe dans TypeScript, également appelée énumération. Elle est généralement utilisée pour gérer plusieurs constantes de la même série (c'est-à-dire des variables qui ne peuvent pas être modifiées), utilisées pour le jugement d'état.

Un jugement de statut courant sur le Web consiste à gérer différents codes de statut de réponse en conséquence lors du traitement des demandes :

const handleResponseStatus = (status: number): void => {
  switch (status) {
    case 200: // 请求成功时
      // Do something...
      break;
    case 400: // 请求失败时
      // Do something...
      break;
    default:
      throw (new Error('No have status code!'));
  }
};

Mais comme les codes de statut de réponse sont tous prédéfinis, il n'y a pas de controverse. Le code est écrit comme c'est normal à voir. procédez de cette façon, mais si le backend personnalise certains codes lorsqu'une erreur se produit sur le serveur et indique au frontend quelles erreurs représentent ces codes, alors la fonction ci-dessus peut devenir comme ceci :

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!'));
  }
};

Si c'est le code, sans parler de la personne qui vient de prendre le relais, même si vous l'avez écrit il y a deux semaines, vous ne pourrez probablement pas vous rappeler ce qu'ils représentent sans parcourir les documents.

Mais si vous faites bon usage d'Enum, vous pouvez éviter la situation ci-dessus.

Utilisation de base

Voyons d'abord comment définir Enum C'est très similaire à l'utilisation d'Object :

enum requestStatusCodes {
  error,
  success,
}

Il n'est pas nécessaire d'ajouter un signe égal entre le contenu et le nom. dans l'Enum entre accolades, plutôt qu'une variable, il est plus approprié de l'appeler une constante, car les valeurs dans Enum ne peuvent pas être modifiées, il n'y a donc pas lieu de s'inquiéter que ces règles définies changent au cours du l'exécution du code, provoquant des erreurs d'exécution.

Et puisque Enum est utilisé pour définir la même série de constantes, ces constantes devraient pouvoir conserver des valeurs spécifiques. C'est vrai, chaque constante d'Enum peut spécifier une valeur spécifique via =. = 来指定具体的值 。

但如果是像前面的 requestStatusCodes ,没有为 errorsuccess 指定具体的值也不会出错,因为 TypeScript 会从 0 开始自动递增定义值,所以签名的 requestStatusCodes 会和下面的结果相同:

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

除了数字外,也可以定义为字串:

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

当然也可以在一个 enum 中设定不同的类型,但这样一点意义都没有:

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

了解基本的 Enum 怎么定义后,接着就来改写前面代码中的 handleResponseStatushandleWrongStatus ,让它们在语义上能够更明确。

首先用 Enum 定义两者的状态描述:

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 => {
  // 如果觉得 requestWrongCodes.missingParameter 太长了,也可以用以下方式:
  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!'));
  }
};

修改后的代码就变得直观多了,因为状态码都被放到了 Enum 中统一管理,所以就能用常量名来代表它们,之后不管过了多久,可以明确的知道这里再做什么,甚至连注解或文档都不用写了,因为代码就是最好的文档。

善用 Enum 能使代码绝对是不可或缺的,但就算没使用 TypeScript 也别灰心,因为 TypeScript 最终会被转换为 JavaScript ,那来看看如何直接用 JavaScript 实现 Enum 吧!

用原生 JavaScript 实现 Enum

在前面说过 Enum 很像 Object ,如果研究一下 Enum 被编译成 javascript 之后的代码,就会发现还真的是 Object。

Enum 被编译后会变成 Key 和 Value 反向对应的对象,这样看起来非常简单,为了方便使用,下面把它的编译方式写成一个函数:

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);

虽然得到的结果相同,但是丧失了 Enum 中最可贵的常量特色,如果不能让它变成不可修改,那就有可能会在代码里不经意地改动它,导致执行结果可能出错,于是可以在最后利用 Object.freeze() ,让外部操作无法新增、删除或重新定义任何 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);

这样就能简单在 JavaScript 中实现 Enum 了。

const Enum 的用法

从前面的 JavaScript 代码中可以看到 Enum 编译过后会变成 Key 和 Value 互相对应的 Object ,也就是说不管是用 Key 还是Value 都可以取出对应的值,

但是如果用 const 声明 Enum ,编译之后就不会产生 Object。

直接看例子,假设我把 responseStateconst 重新生命,且也是以 handleResponseStatus 使用该 Enum 做判断:

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

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

看起来一切正常,不过在编译后的 JavaScript 中,会发现 Enum 并没有产生 Object ,而是直接用 const 声明在 Enum 中的值。

const 声明 Enum 有几个好处:

  • 假设要用到的 Enum 非常多,那在执行时就会不停地使用 IIFE 产生 Object 将 Key 和 Value 绑定到 Object,会造成一些效率上的损失,也会增加内存,但是 const

    Mais si c'est comme le requestStatusCodes précédent, il n'y aura pas d'erreur si aucune valeur spécifique n'est spécifiée pour error ou success, car TypeScript commencera à partir de 0 commence à incrémenter automatiquement la valeur définie, donc les requestStatusCodes signés auront le même résultat que le suivant : 🎜
    const enum responseStatus {
      error = 400,
      success = 200,
    }// 会出错,因为已经没有对象可供查找了
    console.log(responseStatus[400])// 但这个不会有问题,因为编译的时候会直接填值
    console.log(responseStatus.error)// 编译后:
    // console.log(400)
    🎜En plus des chiffres, il peut également être défini comme une chaîne : 🎜rrreee🎜Bien sûr, vous pouvez définir différents types dans une énumération, mais cela n'a aucun sens : 🎜rrreee🎜Après avoir compris comment l'énumération de base est définie, réécrivez le handleResponseStatus et handleWrongStatus dans le code précédent pour les rendre plus sémantiquement explicites. 🎜🎜Utilisez d'abord Enum pour définir les descriptions d'état des deux : 🎜rrreee🎜Puis modifiez le jugement Switch dans handleResponseStatus et handleWrongStatus : 🎜rrreee🎜Le code modifié devient intuitif. Plus , étant donné que les codes d'état sont placés dans Enum pour une gestion unifiée, ils peuvent être représentés par des noms constants, peu importe le temps que cela prend, vous pouvez clairement savoir quoi faire ici, et vous n'avez même pas besoin d'écrire des commentaires ou des documents. le code est la meilleure documentation. 🎜🎜Faites bon usage d'Enum pour rendre votre code absolument indispensable, mais ne vous découragez pas même si vous n'utilisez pas TypeScript, car TypeScript finira par être converti en JavaScript, voyons donc comment implémenter Enum directement dans Javascript ! 🎜🎜Utilisez JavaScript natif pour implémenter Enum🎜🎜J'ai déjà dit qu'Enum est très similaire à Object. Si vous étudiez le code une fois Enum compilé en javascript, vous constaterez qu'il s'agit en réalité d'Object. 🎜🎜Enum deviendra l'objet correspondant inverse de Key et Value après avoir été compilé. Cela semble très simple, pour plus de commodité, écrivons sa méthode de compilation en fonction : 🎜rrreee🎜Bien que le résultat soit le même, il est perdu. la fonctionnalité 🎜constante🎜 la plus précieuse d'Enum, si vous ne pouvez pas la rendre non modifiable, vous pouvez la modifier par inadvertance dans le code, entraînant des erreurs possibles dans les résultats d'exécution, vous pouvez donc utiliser Object.freeze( à la fin), afin que les opérations externes ne puissent pas ajouter, supprimer ou redéfinir une propriété : 🎜rrreee🎜De cette façon, Enum peut être facilement implémenté en JavaScript. 🎜🎜Utilisation de const Enum🎜🎜Vous pouvez voir dans le code JavaScript précédent qu'après compilation, Enum deviendra un objet dont la clé et la valeur correspondent l'une à l'autre, c'est-à-dire que que vous utilisiez Key ou Value, vous pouvez obtenir le. valeur correspondante, 🎜🎜🎜 Mais si vous déclarez Enum avec <code>const, l'objet ne sera pas généré après la compilation. 🎜🎜🎜Regardez directement l'exemple. Supposons que je régénère responseState avec const, et que j'utilise également Enum pour porter des jugements avec handleResponseStatus : 🎜rrreee 🎜 Tout semble normal, mais dans le JavaScript compilé, vous constaterez qu'Enum ne génère pas d'objet, mais utilise directement const pour déclarer la valeur dans Enum. 🎜🎜Utiliser const pour déclarer Enum présente plusieurs avantages : 🎜
    • 🎜En supposant qu'il y ait beaucoup d'Enums à utiliser, puis pendant l'exécution, nous continuerons à utiliser IIFE pour générer un objet et lier la clé et la valeur à l'objet, ce qui entraînera des pertes d'efficacité et augmentera la mémoire, mais const ne générera pas d'objet, donc il n'y aura pas les problèmes ci-dessus. 🎜
    • 就算到的 Enum 不多,判断时也需要一直从 Object 中找出对应的值,而如果是用 const 声明 Enum ,在编译成 JS 时就将声明的值直接放入判断中。

    不过这样也就没法从 Enum 中反向取值了,因为它并不会产生对象:

    const enum responseStatus {
      error = 400,
      success = 200,
    }// 会出错,因为已经没有对象可供查找了
    console.log(responseStatus[400])// 但这个不会有问题,因为编译的时候会直接填值
    console.log(responseStatus.error)// 编译后:
    // console.log(400)

    更多编程相关知识,请访问:编程入门!!

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer