您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

聊聊TypeScript中Enum(枚举)的用法

2024/8/6 3:37:36发布221次查看
本篇文章给大家介绍一下typescript中enum(枚举)语法,聊聊enum的基本用法,如何使用原生javascript来实现enum。
enumenum 是在 typescript 中新增的语法,也叫做枚举,一般用它来管理多个相同系列的常量(即不能被修改的变量),用于状态的判断。
在 web 中比较常见的状态判断,是在处理请求时,要针对不同的响应状态码做对应的处理:
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!')); }};
但因为响应状态码都是预先定义好的,所以没什么争议,代码写成这样看也很正常,但是如果后端在服务器发生错误时自定义了一些编码,并告诉前端,这些代码都代表什么错误,那么上面的函数可能会变成这样:
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!')); }};
如果是这种代码,别说是刚接手的人,就算是你自己两星期前写的,恐怕不去翻文档也想不起它们都代表什么了吧。
但是如果善用 enum ,就可以避免上述发生的情况。
基本用法先来看看 enum 该怎么定义,它和 object 的用法很像:
enum requeststatuscodes { error, success,}
不需要在内容与名称之间加等号,直接在大括号内叙述该 enum 中具有哪些变量,与其说是变量,不如说是常量更恰当些,因为在 enum 中的值是不可修改的,所以也不必担心这些定义好的规则会在代码执行的过程中发生改变,导致执行错误。
而既然 enum 是用来定义同一个系列常量的,那这些常量应该都能维护特定的值。没错,在 enum 中的每个常量,都可以通过 = 来指定具体的值 。
但如果是像前面的 requeststatuscodes ,没有为 error 或 success 指定具体的值也不会出错,因为 typescript 会从 0 开始自动递增定义值,所以签名的 requeststatuscodes 会和下面的结果相同:
enum requeststatuscodes { error = 0, success = 1,}console.log(requeststatuscodes.error) // 0console.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 怎么定义后,接着就来改写前面代码中的 handleresponsestatus 和 handlewrongstatus ,让它们在语义上能够更明确。
首先用 enum 定义两者的状态描述:
enum requeststatuscodes { error = 400, success = 200,}enum requestwrongcodes { missingparameter = 'a', wrongparametertype = 'b', invalidtoken = 'c',}
然后修改 handleresponsestatus 和 handlewrongstatus 中的 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。
直接看例子,假设我把 responsestate 用 const 重新生命,且也是以 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 并不会产生 object ,也就不会有以上的问题。
就算到的 enum 不多,判断时也需要一直从 object 中找出对应的值,而如果是用 const 声明 enum ,在编译成 js 时就将声明的值直接放入判断中。
不过这样也就没法从 enum 中反向取值了,因为它并不会产生对象:
const enum responsestatus { error = 400, success = 200,}// 会出错,因为已经没有对象可供查找了console.log(responsestatus[400])// 但这个不会有问题,因为编译的时候会直接填值console.log(responsestatus.error)// 编译后:// console.log(400)
更多编程相关知识,请访问:编程入门!!
以上就是聊聊typescript中enum(枚举)的用法的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product