You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Object.freeze()后,如何实现状态枚举双向映射以获取键名?

解决冻结对象的双向枚举访问问题

你遇到的问题和Object.freeze()无关,核心原因是你定义的AnimeState只有「键→值」的单向映射,没有添加「值→键」的反向映射关系,所以用值去访问时找不到对应的键名。

先修正代码语法错误

你原代码里Idle = 1的写法不符合对象语法,键值对应该用冒号:分隔,正确的基础定义如下:

const baseAnimeState = {
  Idle: 1,
  Walking: 2,
  Running: 3,
  Attacking: 4,
  Dead: 0,
  Uninitialized: -1
};

实现双向映射+对象冻结的方案

要兼顾双向访问和对象冻结,只需先给对象添加反向映射属性,再执行冻结操作即可:

方案1:手动构建双向映射

// 1. 定义基础键值映射
const baseAnimeState = {
  Idle: 1,
  Walking: 2,
  Running: 3,
  Attacking: 4,
  Dead: 0,
  Uninitialized: -1
};

// 2. 构建双向映射:给对象添加「值→键」的反向属性
const AnimeState = {...baseAnimeState};
for (const [key, value] of Object.entries(baseAnimeState)) {
  AnimeState[value] = key;
}

// 3. 冻结对象,防止后续意外修改
Object.freeze(AnimeState);

// 测试双向访问
this.state = AnimeState.Uninitialized;
console.log(AnimeState[this.state]); // 输出"Uninitialized"
console.log(AnimeState["Running"]); // 输出3

方案2:封装通用枚举生成函数

如果需要多次创建这类双向枚举,可以封装工具函数提升复用性:

function createBidirectionalEnum(enumObj) {
  const result = {...enumObj};
  for (const [key, val] of Object.entries(enumObj)) {
    // 校验值的唯一性,避免反向映射被覆盖
    if (result[val]) {
      console.warn(`枚举值${val}重复,键${key}的反向映射会覆盖已有键${result[val]}`);
    }
    result[val] = key;
  }
  return Object.freeze(result);
}

// 使用函数创建枚举
const AnimeState = createBidirectionalEnum({
  Idle: 1,
  Walking: 2,
  Running: 3,
  Attacking: 4,
  Dead: 0,
  Uninitialized: -1
});

// 测试双向访问
this.state = AnimeState.Uninitialized;
console.log(AnimeState[this.state]); // 输出"Uninitialized"

注意事项

  • 务必保证枚举的值是唯一的,若多个键对应同一个值,后添加的反向映射会覆盖前面的,导致部分键名无法通过值获取。
  • Object.freeze()仅禁止修改对象属性,不会影响已存在属性的正常访问,因此提前构建好双向映射后,冻结状态依然支持双向访问。

内容的提问来源于stack exchange,提问作者Alix Blaine

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 02:17:29