JavaScript中如何更新嵌套对象且保留原有子属性?
如何深度更新嵌套对象并保留原有字段?
原始数据
const data = { "field1": { "name": 'Anuv', "marks": { "eng": 43, "hindi": 23 }, "age": 21 }, "field2": { "school": 'DAV' } }
待更新值
const updatedValue = { "field1": { "name": "Anuv Gupta" } }
期望结果
需要保留所有原有字段,仅更新field1.name:
const expectedData = { "field1": { "name": 'Anuv Gupta', "marks": { "eng": 43, "hindi": 23 }, "age": 21 }, "field2": { "school": 'DAV' } }
问题描述
使用浅合并方法(Object.assign或扩展运算符)时,会直接覆盖field1对象,导致丢失marks和age属性:
// 两种浅合并方式都会丢失field1下的子属性 expectedData = Object.assign({}, data, updatedValue); // 或 expectedData = { ...data, ...updatedValue };
得到的结果:
const obj = { "field1": { "name": 'Anuv Gupta', }, "field2": { "school": 'DAV' } }
解决方案
1. 嵌套使用扩展运算符(适合层级少的场景)
针对嵌套的field1单独做合并,避免直接覆盖整个对象:
const expectedData = { ...data, field1: { ...data.field1, // 保留field1原有所有属性 ...updatedValue.field1 // 覆盖需要更新的属性 } };
2. 嵌套使用Object.assign(逻辑同上)
const expectedData = Object.assign({}, data, { field1: Object.assign({}, data.field1, updatedValue.field1) });
3. 通用深度合并函数(适合多层嵌套场景)
如果对象有更深的嵌套层级,可以写一个通用的深度合并函数,递归处理嵌套对象:
function deepMerge(target, source) { const result = { ...target }; for (const key in source) { // 仅对非数组的对象进行递归合并 if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { result[key] = deepMerge(result[key] || {}, source[key]); } else { // 基础类型直接覆盖 result[key] = source[key]; } } return result; } const expectedData = deepMerge(data, updatedValue);
原因说明
Object.assign和扩展运算符都是浅合并:当合并的属性值是对象时,只会替换引用,不会递归合并对象内部的属性。之前的操作直接用updatedValue.field1替换了data.field1,因此丢失了原有子属性。
内容的提问来源于stack exchange,提问作者komal
相关产品推荐
相关产品推荐

