修复merge函数替换嵌套数组首个对象的问题
如何修改merge函数实现数组对象的精准属性更新?
原merge函数在处理数组时会直接替换数组元素,导致newBody中card.back数组的第一个对象被deviceChanges中的iphoneText对象覆盖,而我们需要保留数组所有原有对象,仅更新匹配key的对象属性。
原函数问题分析
原函数判断typeof value === 'object'时会递归处理,但数组也是object类型,所以会按索引遍历数组元素,把source数组索引0的对象直接覆盖target数组索引0的对象,这不符合需求。
修改后的merge函数
我们需要专门处理数组场景,针对带key属性的数组对象,通过key匹配找到目标对象后再更新属性:
function merge(target, source) { for (const [key, value] of Object.entries(source)) { if (key in target) { // 处理数组:双方都是数组,且元素是带key的对象 if (Array.isArray(target[key]) && Array.isArray(value)) { value.forEach(sourceItem => { // 只处理包含key属性的对象 if (sourceItem && typeof sourceItem === 'object' && 'key' in sourceItem) { // 在目标数组中找到key匹配的对象 const targetItem = target[key].find(item => item.key === sourceItem.key); if (targetItem) { // 递归合并属性,只更新差异部分 merge(targetItem, sourceItem); } else { // 可选:如果目标数组没有该key的对象,追加进去(按需调整) target[key].push(sourceItem); } } }); } // 处理非数组的对象类型,递归合并 else if (typeof value === 'object' && typeof target[key] === 'object') { merge(target[key], value); } // 基本类型直接覆盖 else { target[key] = value; } } else { // 目标对象没有的键,直接添加 target[key] = value; } } return target; }
验证效果
调用merge(newBody, deviceChanges)后,结果会符合预期:
- 顶层属性
a从3更新为5 card.back数组保留所有原对象,仅key为iphoneText的对象的value被更新为UPDATED VALUE FOR IPHONE- 其他属性(如
c:8)保持不变
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

