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

如何在对象初始化时将属性值设为自身变量名(以JS枚举为例)

解决方法

以下几种方案可以满足你避免重复书写键值对的需求,同时符合ES6+、可同步重构、JSDoc识别等要求:

方案1:用Object.fromEntries快速生成(最简洁)

利用ES6+的Object.fromEntries将键数组直接转换为键值相等的对象,配合Object.freeze实现不可变,加上JSDoc标签让编辑器识别为枚举:

class AA {
  /**
   * @enum {string}
   */
  static Color = Object.freeze(
    Object.fromEntries(['Red', 'Green', 'Blue'].map(key => [key, key]))
  );
}
  • 核心优势:仅需维护一个键数组,完全避免重复书写键值对
  • 同步重构:修改数组中的字符串时,使用编辑器的“更改所有匹配项”或重命名功能,可同步更新对象的键和值
  • 调试友好:枚举值为字符串,调试时能直接看到有意义的名称

方案2:自定义辅助函数(复用性强)

如果需要多次创建这类枚举,封装一个辅助函数可以进一步简化操作:

/**
 * 创建键值相等的不可变枚举对象
 * @param {string[]} keys 枚举键名列表
 * @returns {Readonly<Record<string, string>>}
 */
const createEnum = (keys) => Object.freeze(
  Object.fromEntries(keys.map(key => [key, key]))
);

class AA {
  /**
   * @enum {string}
   */
  static Color = createEnum(['Red', 'Green', 'Blue']);
}
  • 优势:后续创建其他枚举只需调用createEnum并传入键数组即可,逻辑复用性高
  • 同样满足不可变、同步重构、JSDoc识别等所有需求

方案3:Proxy动态映射(接近你设想的写法)

如果想要更贴近你示例中“仅写键名,自动赋值为键名”的语法,可以用Proxy拦截属性访问,首次访问时自动赋值:

class AA {
  /**
   * @enum {string}
   */
  static Color = Object.freeze(new Proxy({}, {
    get(target, prop) {
      if (typeof prop === 'string' && !(prop in target)) {
        target[prop] = prop;
      }
      return target[prop];
    }
  }));
}
  • 注意:该方案的枚举键会在首次访问后才被添加到对象中,对自动补全的支持略有不足,适合不需要提前枚举所有键的场景

关键需求匹配说明

  • 简化实现:方案1和2的代码量极少,无需繁琐的重复代码
  • 同步重构:维护数组或变量时,编辑器的重命名功能可一次性同步所有键值
  • JSDoc识别:添加@enum标签后,VSCode会提供完整的枚举自动补全和类型提示
  • 不可变性:所有方案都用Object.freeze冻结对象,防止意外修改
  • 调试友好:枚举值均为字符串,调试时能直观看到对应名称

内容的提问来源于stack exchange,提问作者Nor.Z

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 07:15:33