JS如何仅通过指定属性更新嵌套对象?
如何深度更新嵌套对象(保留未指定键)
问题重现
原对象:
let obj = { a:{ b:{ c:1, d:2, }, e:{ f:3 } } }
待应用的更新对象:
const updateObj = { a:{ b:{ c:"boo" } } }
直接使用Object.assign(obj, updateObj)会得到以下结果,丢失了obj.a.b.d和obj.a.e:
{ a:{ b:{ c:"boo" } } }
我们需要的是仅覆盖更新对象中指定的键,同时保留原对象未提及的所有键值。
解决方案
1. 固定层级:嵌套扩展运算符
如果对象的嵌套层级固定,可以用扩展运算符逐层合并,精准保留未修改的子键:
obj = { ...obj, a: { ...obj.a, b: { ...obj.a.b, ...updateObj.a.b } } };
执行后得到预期结果:
{ a:{ b:{ c:"boo", d:2 }, e:{ f:3 } } }
这种方式直观,但嵌套层级过多时会显得繁琐。
2. 通用场景:递归深度合并函数
如果对象嵌套层级不固定,写一个通用的递归合并函数更高效:
function deepMerge(target, source) { for (const key in source) { // 仅当双方都是非null对象时,递归合并子对象 if (typeof source[key] === 'object' && source[key] !== null && typeof target[key] === 'object' && target[key] !== null) { deepMerge(target[key], source[key]); } else { // 非对象类型直接覆盖 target[key] = source[key]; } } return target; } // 调用方式 deepMerge(obj, updateObj);
这个函数能处理任意层级的嵌套对象,自动保留所有未指定的键值。如果不想修改原对象,可以先通过structuredClone(obj)复制一份再传入函数。
内容的提问来源于stack exchange,提问作者Flynn Hillier
相关产品推荐
相关产品推荐

