JavaScript数组对象存在则覆盖否则新增时||兜底逻辑失效问题
问题根因
你的|| obj兜底逻辑本身没有问题,不符合预期的核心原因是你对Array.map()的作用存在认知偏差:
Array.map()只会遍历原数组的每一项做转换处理,返回的新数组长度和原数组完全相等,不会自动追加原数组中不存在的元素。- 你写的
find(...) || obj逻辑,作用范围仅限当前遍历到的原数组元素:如果在待匹配数组里找不到和当前原元素name一致的项,就保留当前原元素,它根本不会处理待匹配数组里那些原数组压根没有的项。
对应你的代码表现:
- 覆盖
test1的逻辑能生效,是因为test1本来就在原数组里:当map遍历到原数组中name为test1的项时,find能在elementThatAllreadyExists里找到匹配项,就会用新元素替换旧元素,其余3个原数组项找不到匹配就走兜底保留原值,这部分和你的预期一致。 test33没有被追加,是因为原数组里根本不存在name为test33的项:map遍历全程只会处理原数组里的test1、test2、test3、test4四个元素,永远不会遍历到newElement里的test33,自然不可能把它加进结果数组里。
正确实现「同name覆盖、无name追加」的方案
如果要实现你要的合并效果,不能单独使用map,可以用Map做去重合并,参考代码:
// 按name属性合并数组:同name的项用新值覆盖,新name的项追加到结果中 function mergeByName(origin, updates) { const itemMap = new Map(origin.map(item => [item.name, item])) updates.forEach(item => itemMap.set(item.name, item)) return Array.from(itemMap.values()) } // 测试效果 const updatedArr1 = mergeByName(arr, newElement) // 结果包含原4个元素 + name为test33的新元素,共5项 const updatedArr2 = mergeByName(arr, elementThatAllreadyExists) // 结果中name为test1的元素被新值覆盖,其余3个元素保留,共4项
内容的提问来源于stack exchange,提问作者Ladefuss
相关产品推荐
相关产品推荐

