JavaScript对象问题:如何用roles值替代键作为其他对象属性键
重构角色引用结构,直接使用角色值作为属性键
我完全懂你的痛点——现在的结构里,roles对象的键(比如harvester)成了唯一的引用入口,但实际有意义的是它对应的值(比如"Harvester"),结果别人给你这个值的时候,你还得绕一圈找对应的键,完全浪费了这个值的作用。下面给你具体的重构方案:
第一步:先看原来的问题结构
假设你现在的代码大概是这样的:
// 原来的roles定义:键是内部标识,值是对外的角色名称 const roles = { harvester: "Harvester", upgrader: "Upgrader", builder: "Builder" }; // 其他地方引用creep时,用的是roles的键 const creepsByRole = { harvester: [creep1, creep2], upgrader: [creep3], builder: [creep4] }; // 如果别人给你"Harvester",你得先找对应的键才能用 function getCreepsByRoleName(roleName) { // 遍历roles找键,很麻烦 const roleKey = Object.keys(roles).find(key => roles[key] === roleName); return creepsByRole[roleKey]; }
这种结构完全把roles的值变成了摆设,还增加了额外的映射逻辑,完全没必要。
第二步:重构为用角色值作为核心引用键
我们直接把roles的结构反过来,让对外的角色名称(比如"Harvester")作为键,同时把原来的内部标识(如果还有用的话)放到角色配置里:
方案1:简化版(不需要保留内部键)
如果原来的内部键(比如harvester)只是用来映射角色名称,没有其他用途,直接改成这样:
// 现在roles的键就是对外的角色名称,值可以放角色的配置(比如工作逻辑、身体部件等) const roles = { "Harvester": { bodyParts: [WORK, CARRY, MOVE], run: (creep) => { /* 采集逻辑 */ } }, "Upgrader": { bodyParts: [WORK, CARRY, MOVE, MOVE], run: (creep) => { /* 升级控制器逻辑 */ } } }; // creepsByRole直接用角色名称作为键 const creepsByRole = { "Harvester": [creep1, creep2], "Upgrader": [creep3] }; // 现在别人给你"Harvester",直接就能用 function getCreepsByRoleName(roleName) { return creepsByRole[roleName]; }
方案2:保留内部标识(如果原来的键还有其他用途)
如果原来的内部键(比如harvester)还用来关联其他逻辑(比如函数名、数据库标识),可以把它放到角色配置里:
const roles = { "Harvester": { internalKey: "harvester", bodyParts: [WORK, CARRY, MOVE], run: (creep) => { /* 采集逻辑 */ } }, "Upgrader": { internalKey: "upgrader", bodyParts: [WORK, CARRY, MOVE, MOVE], run: (creep) => { /* 升级控制器逻辑 */ } } }; // creepsByRole依然用角色名称作为键 const creepsByRole = { "Harvester": [creep1, creep2], "Upgrader": [creep3] };
方案3:用常量避免拼写错误
为了防止手动输入角色名称时拼写错误,可以把角色名称定义成常量,然后用常量作为键:
// 定义角色名称常量 const ROLE_HARVESTER = "Harvester"; const ROLE_UPGRADER = "Upgrader"; const roles = { [ROLE_HARVESTER]: { bodyParts: [WORK, CARRY, MOVE], run: (creep) => { /* 采集逻辑 */ } }, [ROLE_UPGRADER]: { bodyParts: [WORK, CARRY, MOVE, MOVE], run: (creep) => { /* 升级控制器逻辑 */ } } }; const creepsByRole = { [ROLE_HARVESTER]: [creep1, creep2], [ROLE_UPGRADER]: [creep3] }; // 使用时直接用常量 const harvesters = creepsByRole[ROLE_HARVESTER];
重构后的好处
- 直接使用有语义的角色名称作为引用键,代码更直观
- 外部传入角色值时无需额外映射,直接就能用
- 消除了冗余的键值对映射,减少不必要的代码逻辑
内容的提问来源于stack exchange,提问作者Pavlin Petkov
相关产品推荐
相关产品推荐

