问: 在 TS 中普通枚举和常量枚举有什么区别?

引言

TS 中枚举(enum)是一个比较常用的语法, 通俗来说, 枚举就是对一个对象的所有可能取到的值的集合, 枚举的定义方式与结构体和联合体相似, 其形式为:

ts 复制代码
enum 枚举名{
  标识符①[=整型常数],
  标识符②[=整型常数],
  ...
  标识符N[=整型常数],

也许你看到过下面这两种枚举(enum)定义的方式:

ts 复制代码
// 普通枚举
enum Color { Red, Green, Blue }

// 常量枚举(使用 const)
const enum Color { Red, Green, Blue }

那么问题来了, 这两种定方式有什么区别呢?

其实上面两种声明方式唯一的区别就在于编译结果上有所不同, 下面我们将对其展开简单说明, 对于 TS 枚举的基本使用, 语法这边就不展开讲解了

一、普通枚举

如下我们使用 普通枚举 的方式, 声明了一个枚举 Color

ts 复制代码
// 普通枚举
enum Color { Red, Green, Blue }

下面我们可以在 Typescript 游乐场 来看下上面 TS 编译后的结果

从图中我们会发现 普通枚举 编译后的 JS 代码是会去创建一个对象 Color, 然后往对象上添加一些列的值。这里我们可以在自己项目中测试下, 打印出 Color 看看它是长啥样的

如上图, 可以看出, 最终编译后生成的 Color 对象实际上是一组 key => value 以及 value => key 的一个映射表

ts 复制代码
// 普通枚举
enum Color { Red, Green, Blue }

Color.Red // 0
Color[2] // "Blue"

对于普通枚举, 最终编译出来的就是一个普通的对象, 如上代码译出来的 Color 就是一个普通的对象, 之后 Color 是有可能被篡改的(尽管它们是只读的, 但我们依然是有办法修改的)

ts 复制代码
// 普通枚举
enum Color { Red, Green, Blue }

Color.Blue; // 2

// Color 中属性都是只读的, 可通过 Object.defineProperty 进行修改
Object.defineProperty(Color, 'Blue', { writable: true, value: 666 });

Color.Blue; // 666
Color.Blue; // 666

二、常量枚举

那么相对于普通枚举(只使用 enum 进行声明), 常量枚举(使用 const + enum 进行声明)在编译结果上又有什么不一样呢?

如下我们使用 常量枚举 的方式, 声明了一个枚举 Color

ts 复制代码
// 常量枚举(使用 const)
const enum Color { Red, Green, Blue }

const red = Color.Red
const red = Color.Green

下面我们可以在 Typescript 游乐场 来看下上面 TS 编译后的结果

TS 编译后的结果会发现, 常量枚举和普通枚举的差异还是很大的, 对于常量枚举会在 TS 编译期间被删除, 常量枚举的成员在使用的地方会被替换为对应的值

三、总结

  1. 普通枚举 enum A {...} 和常量枚举 const enum A {...} 之间的区别主要在于 TS 的编译结果上有所差别
  2. 普通枚举 enum A {...}, 会将其编译为一个 JS 对象, 对象内就是枚举成员和值的一个相互映射
  3. 常量枚举 const enum A {...}, 编译后不会生成任何代码, 会删除 TS 部分内容, 对于使用到的成员只会进行值的替换
  4. 由此可见, 使用 常量枚举 会有更好的性能, 避免额外的性能开销; 那么大部分情况下我们更推荐使用常量枚举, 那么问题来了我们什么时候使用普通枚举呢? 答案是俺也没找到答案😭😭😭😭

四、参考

相关推荐
雪隐1 小时前
个人电脑玩AI-16让5060 Ti给你打工——MiniMax H3 提速实录:从"泡杯茶等视频"到"视频等你",一张 5060 Ti 的自我修养
前端·人工智能·后端
FungLeo2 小时前
Flutter Web 中文字体困境与渲染器选择:CanvasKit vs HTML renderer 实战
前端·flutter·html
BD_Marathon2 小时前
部署Spark
大数据·javascript·spark
敲代码的玉米C2 小时前
我修的那个 bug,制造了另一个 bug
前端·人工智能·架构
gis开发之家2 小时前
《Vue3 从入门到大神50篇》Vue3 源码详解(二十):生命周期钩子源码解析 —— onMounted / onUpdated 如何实现?
前端·javascript·前端框架·vue3·vue3源码
全栈项目管理程序猿2 小时前
ArcGIS JS 基础教程(9):天空盒与大气效果
javascript
Narrastory2 小时前
我用 Claude Code 写代码不到 2 小时,却花了 3 天做完这个软件—Vibe Coding 的正确姿势,是设计不是生成
前端·人工智能·github
Enaium2 小时前
我实现了KMP的SDL绑定并编写了高性能软光追
前端·kotlin
古夕2 小时前
本地正常线上白屏:一次路由切换后刷新恢复问题的排查与修复
前端·ai编程
栀鸢ouo2 小时前
解决Element Plus表格展开行横向溢出、滚动截断问题(项目实战方案)
前端·vue.js