JS中合并对象时如何保留嵌套数组并覆盖指定元素?
如何用扩展运算符合并对象时保留嵌套数组元素并覆盖指定项
扩展运算符仅能实现浅层次的对象属性合并,对于数组这类引用类型,后续对象的数组会直接替换掉前面的数组,而非合并元素。要实现保留原有数组元素、仅覆盖指定项的需求,需要单独针对嵌套数组编写合并逻辑。
方案1:按数组元素的唯一标识覆盖(匹配替换)
如果你的数组元素是带有唯一标识属性的对象(比如示例中hobbies元素的a/b键),可以通过以下步骤实现:
- 收集所有对象的
hobbies元素; - 以元素的唯一标识为键,用
reduce合并,后续元素覆盖同标识的旧元素; - 将合并后的数组替换到最终对象中。
const person1 = {name: 'Jack', age: 10, job: 'developer', hobbies: [{a:'baseball'}, {b:'basketball'}]} const person2 = {name: 'Su', age: 20} const person3 = {name: 'Jin', job: 'singer', hobbies: [{a:'sing'}]} // 收集所有hobbies元素,空数组避免无该属性时报错 const allHobbies = [ ...(person1.hobbies || []), ...(person2.hobbies || []), ...(person3.hobbies || []) ]; // 按元素的第一个属性作为唯一标识,合并时覆盖旧元素 const mergedHobbies = Object.values(allHobbies.reduce((acc, hobby) => { const uniqueKey = Object.keys(hobby)[0]; acc[uniqueKey] = hobby; return acc; }, {})); // 合并对象并替换hobbies const result = { ...person1, ...person2, ...person3, hobbies: mergedHobbies }; console.log(result); // 输出:{name: 'Jin', age: 20, job: 'singer', hobbies: [{a:'sing'}, {b:'basketball'}]}
方案2:直接追加所有数组元素(不覆盖)
如果仅需要保留所有数组元素(不做覆盖),可以直接合并所有hobbies数组:
const result = { ...person1, ...person2, ...person3, hobbies: [...(person1.hobbies || []), ...(person2.hobbies || []), ...(person3.hobbies || [])] }; console.log(result); // 输出:{name: 'Jin', age: 20, job: 'singer', hobbies: [{a:'baseball'}, {b:'basketball'}, {a:'sing'}]}
说明
扩展运算符的核心是浅拷贝,无法自动处理嵌套引用类型的合并。如果你的对象有多个嵌套属性需要处理,可以封装通用的深度合并函数,但针对单个属性(比如示例中的hobbies),手动处理更高效。
内容的提问来源于stack exchange,提问作者Lee SeongBae
相关产品推荐
相关产品推荐

