🙅你真的懂enum吗,详细介绍enum的坑点

1. 编译方式

  • 普通 enum

    编译时会生成一个运行时对象,将枚举名称和值双向映射。例如:

    typescript 复制代码
    enum Direction {
      Up = 'UP',
      Down = 'DOWN',
    }

    编译为:

    javascript 复制代码
    var Direction;
    (function (Direction) {
      Direction["Up"] = "UP";
      Direction["Down"] = "DOWN";
    })(Direction || (Direction = {}));

    运行时可以通过 Direction.UpDirection["Up"] 访问值。

  • const enum

    完全在编译阶段被内联替换,不会生成任何运行时对象。例如:

    typescript 复制代码
    const enum Direction {
      Up = 'UP',
      Down = 'DOWN',
    }
    console.log(Direction.Up);

    编译为:

    javascript 复制代码
    console.log("UP"); // 直接替换为字面量

    若启用 preserveConstEnums 选项,会生成对象但不影响内联行为。


2. 运行时存在性

  • 普通 enum
    生成的枚举对象在运行时存在,支持动态访问(如 Object.keys(Direction))。
  • const enum
    默认不存在于运行时(除非启用 preserveConstEnums),无法动态访问或反射。

3. 性能

  • 普通 enum
    运行时需查找对象,可能存在轻微性能开销。
  • const enum
    直接替换为字面量,无运行时开销,适合高频使用的场景。

4. 成员值的限制

  • 普通 enum

    • 允许常量成员(如字符串、数字字面量)和计算成员(如函数返回值)。

    • 支持延迟求值(引用其他成员):

      typescript 复制代码
      enum NormalEnum {
        A = 1,
        B = A * 2, // 允许,B = 2
      }
  • const enum

    • 所有成员必须是常量表达式(无法使用计算值):

      typescript 复制代码
      const enum ConstEnum {
        A = 1,
        B = A * 2, // 允许,因为 A 是常量
        // C = Math.random(), // 错误:必须是常量
      }

5. 使用场景

  • 普通 enum

    • 需要运行时动态访问或反射(如遍历成员)。
    • 需要跨模块或环境声明。
    • 支持声明合并(多次声明合并为一个)。
  • const enum

    • 追求极致性能或减少代码体积。
    • 无需运行时枚举对象(如仅静态类型检查)。

6. 调试

  • 普通 enum
    运行时对象可见于调试工具,便于检查。
  • const enum
    被内联为字面量,调试时无法查看原始枚举结构。

7. 跨模块与编译选项

  • 普通 enum

    无需特殊处理即可跨文件使用。

  • const enum

    • 若跨模块使用,需确保编译配置正确(如 isolatedModules 下可能需启用 preserveConstEnums)。
    • 内联值的替换依赖编译时的类型信息。

8. 示例对比

  • 普通 enum 的灵活性:

    typescript 复制代码
    enum LogLevel {
      Error = 0,
      Warn = 1,
      Info = calculateInfoLevel(), // 允许计算成员
    }
  • const enum 的内联优化:

    typescript 复制代码
    const enum HttpCode {
      OK = 200,
      NotFound = 404,
    }
    // 编译后:console.log(200);
    console.log(HttpCode.OK);

总结表格

特性 普通 enum const enum
运行时对象 生成 默认不生成(可配置保留)
性能 动态查找,稍慢 内联替换,更快
成员类型 允许常量和计算值 仅允许常量表达式
动态访问 支持(如 Object.keys() 不支持
跨模块/文件 直接支持 需配置支持
调试友好性 否(仅见字面量)
适用场景 需要运行时逻辑或反射 高频使用、追求性能与代码简洁

何时选择?

  • 普通 enum:需要运行时枚举对象、动态访问、计算成员或环境声明。
  • const enum:追求性能优化、代码精简,且无需运行时枚举逻辑。
相关推荐
月下点灯10 分钟前
🔄记住这张图,脑子跟着浏览器的事件循环(Event Loop)转起来了
前端·javascript·浏览器
邹小邹-AI14 分钟前
Rust + 前端:下一个十年的“王炸组合”
开发语言·前端·rust
行走在顶尖16 分钟前
vue3+ant-design-vue
前端
华仔啊1 小时前
图片标签用 img 还是 picture?很多人彻底弄混了!
前端·html
lichong9511 小时前
XLog debug 开启打印日志,release 关闭打印日志
android·java·前端
烟袅1 小时前
作用域链 × 闭包:三段代码,看懂 JavaScript 的套娃人生
前端·javascript
风止何安啊2 小时前
收到字节的短信:Trae SOLO上线了?尝尝鲜,浅浅做个音乐播放器
前端·html·trae
抱琴_2 小时前
大屏性能优化终极方案:请求合并+智能缓存双剑合璧
前端·javascript
用户463989754322 小时前
Harmony os——长时任务(Continuous Task,ArkTS)
前端
fruge2 小时前
低版本浏览器兼容方案:IE11 适配 ES6 语法与 CSS 新特性
前端·css·es6