如何在不覆盖整个对象的情况下修改指定对象属性?
实现任意层级嵌套对象的动态属性更新(避免覆盖未修改字段)
问题描述
需要将修改对象的指定属性更新到目标对象中,同时保留原对象的所有未修改字段(包括嵌套对象属性、顶级字段),支持任意层级的嵌套结构,包括对象和带key标识的数组元素更新。现有代码仅能处理两层嵌套,无法应对深层对象或数组场景。
解决方案:深度递归更新函数
编写一个递归函数,根据值的类型(对象、数组、基本类型)分别处理,实现深度合并更新:
核心函数代码
function deepUpdate(target, changes) { // 遍历修改对象的每个键值对 for (const [key, value] of Object.entries(changes)) { // 目标对象无该键时直接赋值 if (!(key in target)) { target[key] = value; continue; } const targetValue = target[key]; const isTargetObj = typeof targetValue === 'object' && targetValue !== null && !Array.isArray(targetValue); const isChangeObj = typeof value === 'object' && value !== null && !Array.isArray(value); const isTargetArr = Array.isArray(targetValue); const isChangeArr = Array.isArray(value); // 递归更新嵌套对象 if (isTargetObj && isChangeObj) { deepUpdate(targetValue, value); } // 按key匹配更新数组中的对象元素 else if (isTargetArr && isChangeArr) { const targetMap = new Map(targetValue.map(item => [item.key, item])); for (const changeItem of value) { if (changeItem.key && targetMap.has(changeItem.key)) { deepUpdate(targetMap.get(changeItem.key), changeItem); } else { // 可选:添加新元素到数组 targetValue.push(changeItem); } } } // 基本类型或不匹配类型直接替换 else { target[key] = value; } } return target; }
测试场景1:数组元素按key更新
使用你提供的设备配置示例测试:
const deviceChanges = { "a": 5, "card": { "back": [ { "key": "iphoneText", "label": "IPHONE", "value": "UPDATED VALUE FOR IPHONE" }, ] } }; let newBody = { "a": 3, "card": { "back": [ { "key": "androidText", "label": "ANDROID", "value": "androidOS" }, { "key": "samsungText", "label": "SAMSUNG", "value": "samsungOS" }, { "key": "iphoneText", "label": "IPHONE", "value": "iphone" }, { "key": "macbookText", "label": "MACBOOK", "value": "macbookOS" } ] }, "c": 8 }; // 执行更新 deepUpdate(newBody, deviceChanges); console.log(newBody);
执行后,newBody的a字段会被更新为5,card.back中的iphoneText元素的value会被替换,其他数组元素和顶级字段c都会保留。
测试场景2:深层嵌套对象更新
针对多层嵌套的对象场景测试:
const changes = { "b": { "x": "new", "y": { "n": "iphone" } } }; let target = { "b": { "x": "old", "y": { "m": "android" }, "z": "keep" }, "d": 10 }; // 执行更新 deepUpdate(target, changes); console.log(target);
执行后,target.b.x会被更新为new,target.b.y.n会被添加,target.b.y.m和target.b.z、target.d都会保留原数值。
函数特性
- 支持任意层级的对象嵌套更新,不会覆盖未修改的属性
- 针对数组中带
key标识的对象元素,自动匹配key进行精准更新,保留其他数组元素 - 基本类型字段直接替换值
- 目标对象不存在的字段会直接从修改对象中添加
内容的提问来源于stack exchange,提问作者bob
相关产品推荐
相关产品推荐

