JavaScript对象添加数据时如何避免原有同名属性被覆盖
对象展开合并同名属性覆盖问题解决方案
JS对象展开运算符的合并规则是位置靠后的同名属性会覆盖靠前的属性,你当前的写法将新传入的cardId、cardName放在...optIn之后,自然会覆盖源对象内的同名属性,根据新值的存储需求,可选择以下实现方式:
方案1:新值重命名作为平级属性存储
如果需要新值和原有属性保持平级,直接给新传入的两个值设置不冲突的属性名即可,是最简单直观的实现:
const addCardData = { ...optIn, // 自定义新属性名,避免和原有cardId、cardName冲突 updatedCardId: cardId, updatedCardName: cardName }
这种写法没有嵌套结构,后续取值逻辑简单,适合新值和原有属性需要同级调用的场景。
方案2:新值收拢为子对象存储
如果不想修改属性名,可将新传入的两个值统一放在自定义子对象下,从结构上避免同名冲突:
const addCardData = { ...optIn, // 自定义子对象存放新传入的卡片信息 extraCardInfo: { cardId, cardName } }
这种写法结构更规整,不会污染源对象展开后的一级属性空间,适合新传入值属于附加配置类信息的场景。
不推荐的写法:调整展开顺序
如果把新传入的属性放在...optIn之前,源对象的同名属性会覆盖新值,最终对象里不会保留新传入的cardId、cardName,不符合你同时存新值的需求,仅当你不需要保留新传入的同名值时才可使用:
// 注意:该写法新传入的cardId、cardName会被optIn内的同名属性覆盖,不会存入最终对象 const addCardData = { cardId, cardName, ...optIn }
实现注意事项
- 若项目中引入了Lodash等工具库,可使用
_.merge做深度合并,但该方法对一级同名属性的覆盖逻辑和展开运算符完全一致,仅会对嵌套对象属性做深度合并,平级同名属性的冲突依然需要靠上述两种方案处理。 - 无需写遍历对象判断属性是否存在的手动赋值逻辑,代码冗余度高,可读性远低于直接构造对象字面量的写法。
- 若后续业务逻辑需要同时用到新旧两组
cardId、cardName,优先选择子对象存储或者明确重命名属性的方案,不要靠调整展开顺序丢弃新值,避免后续取值出现预期外的问题。
内容的提问来源于stack exchange,提问作者risky last
相关产品推荐
相关产品推荐

