如何用数组嵌套对象更新目标对象且保留指定属性?
嘿,我来帮你搞定这个对象更新的问题!根据你的需求,我们要做的是用数组里的多个小对象去更新目标对象,同时必须保住seria属性的原值不变。先结合你给的示例理清楚核心规则:
seria属性铁打不动,不管更新数组里有没有这个属性,都保留原对象的数值;- 原对象没有的属性(比如
LCDscreen、weight),直接从更新数组里加进去; - 原对象已有的其他属性,按你示例里的
model来看,是会被更新数组里最后出现的对应值覆盖(原model:5变成了6);不过你示例里wheels原是4,更新数组里有wheels:5但结果还是4,这要么是笔误,要么是你对某些属性有特殊的保留需求,我后面会给出两种适配的实现方案。
最优实现方案1:简洁的ES6展开语法
这种方式用Object.assign把更新数组里的所有对象先合并成一个,再和原对象合并,最后强制把seria改回原值,代码超清爽:
function updateTarget(target, updates) { // 把数组里的所有更新对象合并成一个大对象 const mergedUpdates = Object.assign({}, ...updates); // 合并原对象和更新对象,最后强制保留原seria return { ...target, ...mergedUpdates, seria: target.seria }; } // 测试你的示例 const mazda = { model: 5, seria: 22, wheels: 4 }; const newItems = [ { LCDscreen: true }, { wheels: 5 }, { model: 6 }, { weight: 500 }, { mirrors: 4 }, ]; const result = updateTarget(mazda, newItems); console.log(result); // 输出:{ model: 6, seria: 22, wheels: 5, LCDscreen: true, weight: 500, mirrors: 4 }
如果你想要的是原对象已有的属性全都保留,只加新属性(对应你示例里wheels没被更新的情况),那稍微改一下,过滤掉更新对象里原对象已经有的属性就行:
function updateTarget(target, updates) { const mergedUpdates = Object.assign({}, ...updates); // 只保留原对象没有的属性 const filteredUpdates = Object.fromEntries( Object.entries(mergedUpdates).filter(([key]) => !target.hasOwnProperty(key)) ); return { ...target, ...filteredUpdates, seria: target.seria }; } // 测试后输出:{ model: 5, seria: 22, wheels: 4, LCDscreen: true, weight: 500, mirrors: 4 }
最优实现方案2:灵活的reduce遍历
如果以后你想加更复杂的规则(比如某些属性允许更新,某些必须保留),用reduce遍历更新数组的方式更灵活,能自定义每一步的逻辑:
function updateTarget(target, updates) { // 先复制原对象,避免修改原数据 return updates.reduce((updatedObj, currentItem) => { // 遍历当前更新对象的每个属性 Object.entries(currentItem).forEach(([key, value]) => { // 跳过seria,不允许修改 if (key === 'seria') return; // 这里可以加自定义规则,比如:只有原对象没有这个属性才添加 // if (!updatedObj.hasOwnProperty(key)) { // updatedObj[key] = value; // } // 或者直接覆盖已有属性(对应model被更新的情况) updatedObj[key] = value; }); // 强制把seria改回原对象的值 updatedObj.seria = target.seria; return updatedObj; }, { ...target }); }
怎么选?
- 要是你只需要“更新数组最后出现的属性覆盖原对象,除了seria”,方案1的第一种写法最简洁高效,性能也拉满;
- 要是你要“原对象已有属性全保留,只加新属性”,方案1的第二种写法就合适;
- 要是以后有复杂的自定义规则(比如针对不同属性设置不同更新逻辑),方案2的
reduce方式更能打。
内容的提问来源于stack exchange,提问作者Viktor Russe
相关产品推荐
相关产品推荐

