TypeScript中的枚举和普通对象的区别

背景

我第一次遇到这个问题是在一次面试中,面试官和我聊到枚举,然后他问了我这个问题,当时我有点懵,我也没想过这个问题,可能是我使用枚举的次数太少了。我那时候自认为这个问题应该不是很难,应该只是我理解不到位而已,我往上搜一下,应该就能知道答案了,所以后面我也没有找面试官要这个问题的答案。之后这个问题就一直在我脑海中,我在搜索引擎搜索了相关问题,但是我对答案都不是很满意,没有办法说服自己。随着自己使用 typescript 的深入,自己也慢慢地理解这个问题。所以记录一下这次感悟。

枚举编译之后就是对象

不知道大家有没有留意过枚举,编译过后的样子,一个 DayEnum 编译之后的样子

enum DayEnum {
    day = '天',
    week = '周',
    month = '月',
    year = '年'
}
"use strict";
var DayEnum;
(function (DayEnum) {
    DayEnum["day"] = "\u5929";
    DayEnum["week"] = "\u5468";
    DayEnum["month"] = "\u6708";
    DayEnum["year"] = "\u5E74";
})(DayEnum || (DayEnum = {}));

这样看起来,和对象好像没有什么区别,如果我们建立一个对象,也能建立 keyvalue 的映射

const DayEnum = {
	day: '天',
    week: '周',
    month: '月',
    year: '年'
}

好像枚举和对象没有什么区别,于是我翻了一下 Typescript 中文网 ,看到了 反向映射 ,我心想,要是枚举能反向映射的话,这就厉害了,这是 JavaScript 中对象做不到的,于是就想起了以前要做反向映射遍历对象 key 的那种痛苦,觉得有救了。然后看到了一句不怎么起眼但让我绝望的话:

要注意的是 不会为字符串枚举成员生成反向映射。

这……也就是说,我的枚举要对应数字类型才可以,比如

enum DayEnum {
    day = 1,
    week = 2,
    month = 3,
    year = 4
}

但是我觉得如果是 1、2、3、4 的话,代码的可读性会差很多吧,一般来说,正常的开发都会尽量去避免这种 “魔法数字”。不过之前的业务中也有遇到过。不过这里有个细节,一定要小心,应该枚举对数字类型生成了反向映射,所以在遍历的时候,会出现下面这种情况:

for (const key in DayEnum) console.log(key)

原来的 value 值也会出现在 key 中,使用反向映射时,遍历枚举类型要注意咯
在这里插入图片描述
可以在typescript 的 playground 中尝试一下!

枚举类型不可以被修改

最后让我感觉枚举类型和普通对象的区别的是这么一段代码

// 这段代码是可以正常运行的
const DayEnum = {
	day: '天',
    week: '周',
    month: '月',
    year: '年'
}
DayEnum.day = 'day'
enum DayEnum {
    day = '天',
    week = '周',
    month = '月',
    year = '年'
}
// 这段代码没法通过编译的
DayEnum.day = 'day'

Cannot assign to ‘day’ because it is a read-only property.

我在想是不是可以这样理解:枚举是一个 只读类型 的对象

总结

后来我思考了一阵子,我感觉是自己对 TypeScript 的理解还只是 JavaScript 的另一种写法,随便加个类型就行,不行就 any,没有从 JavaScript 的思维中走出来。从枚举这个问题上来看,如果用对象的话,这就是一个潜在的问题,而且你可能永远都不会发现,但是用 TypeScipt 的话,你可以避免这种问题的发生,他避免得你甚至都毫无察觉。对日常中的代码还是要多一些思考,细心一点,我相信没有学不到东西的岗位,只有不够细心的“打工人”

  • 15
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值