为何Object.assign未合并所有源对象,实际出现覆盖而非合并的问题
问题原因
Object.assign()会按传入顺序将源对象的可枚举属性复制到目标对象,若后续源对象存在与前面相同的键,后出现的键值会直接覆盖先出现的键值。你最终仅得到100个键的对象,说明你传入的4个源对象中,后3个对象的所有键都与第一个100键对象的键完全重复。- 结合你补充的信息“其中一个100键对象是由前一个100键对象和最后70键对象组合而成”,可以确定你多个请求返回的
results对象存在大量重复键,而非你预想的所有键全局唯一。
解决方案
第一步:先排查重复键
你可以先执行以下代码确认重复键的存在,定位是哪部分请求返回了重复数据:
return await axios .all(requests) .then( axios.spread(async (...responses) => { let fish = [...responses].map((e) => e.data.results); // 提取所有键并筛选重复项 const allKeys = fish.flatMap(obj => Object.keys(obj)); const duplicateKeys = [...new Set(allKeys.filter((key, idx) => allKeys.indexOf(key) !== idx))]; console.log('重复键列表:', duplicateKeys); // 确认无重复后再合并 let newFish = Object.assign({}, ...fish); console.log(fish, 'and', newFish); }), )
第二步:实现无覆盖合并
确认所有键全局唯一后,你可以选择以下任意一种方式实现合并,两种方式逻辑完全一致:
方式1:保留原有Object.assign写法
只要没有重复键,原有写法本身可以直接得到包含全部370个键的对象,不需要额外修改。
方式2:用对象展开运算符实现
let newFish = fish.reduce((total, current) => ({...total, ...current}), {});
特殊场景适配:如果你的results实际是数组格式
如果你实际返回的results是[{id: 'xxx', value: 'xxx'}, ...]格式的数组,而非键值对对象,需要先扁平化数组再转对象:
let newFish = Object.fromEntries( fish.flat().map(item => [item.id, item]) );
内容的提问来源于stack exchange,提问作者Alexander Hemming
相关产品推荐
相关产品推荐

