🙅你真的懂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:追求性能优化、代码精简,且无需运行时枚举逻辑。
相关推荐
吴声子夜歌4 分钟前
Node.js——npm包管理器
前端·npm·node.js
海兰4 分钟前
使用 TypeScript 创建 Elasticsearch MCP 服务器
服务器·elasticsearch·typescript·mcp
小码哥_常4 分钟前
告别启动页“翻车”!Android最新SplashScreen方案全解析
前端
We་ct5 分钟前
LeetCode 373. 查找和最小的 K 对数字:题解+代码详解
前端·算法·leetcode·typescript·二分·
薛一半6 分钟前
React组件通信初识
前端·react.js·前端框架
aesthetician7 分钟前
Tanstack Start:路由魔法与前后端一体化的前端新星!✨
前端
C澒3 小时前
微前端容器标准化:容器标准化能力的 “配置化+ 插件化”
前端·架构
anOnion9 小时前
构建无障碍组件之Carousel Pattern
前端·html·交互设计
ssshooter9 小时前
Tauri 2 iOS 开发避坑指南:文件保存、Dialog 和 Documents 目录的那些坑
前端·后端·ios
Можно10 小时前
深入理解 ES6 Proxy:与 Object.defineProperty 的全面对比
前端·javascript·vue.js