嵌套对象对比时误判imagens与lotes存在差异的问题排查
修复对象对比函数中嵌套数组的误判问题
问题背景
需要实现一个对象对比函数getNew,用于找出两个对象间值有差异的键(确定需更新的字段)。但当前版本在对比包含imagens、lotes这类嵌套数组的对象与自身时,错误判定这些数组存在差异。
问题根源
原函数大概率使用了浅对比(直接用===比较值):
- 数组属于引用类型,即使两个数组内容完全一致,它们的内存引用不同,
===会返回false - 嵌套对象/数组未做递归深度对比,导致误判
修复方案
以下是实现深度对比的getNew函数,支持处理嵌套对象、数组及基本类型:
function getNew(oldObj, newObj) { const diff = {}; // 深度对比两个值是否完全相等 const isEqual = (a, b) => { // 基本类型/引用直接相等 if (a === b) return true; // 处理null/undefined边界 if (a == null || b == null) return a === b; // 数组对比:长度一致且每个元素深度相等 if (Array.isArray(a) && Array.isArray(b)) { if (a.length !== b.length) return false; return a.every((item, idx) => isEqual(item, b[idx])); } // 对象对比:键集一致且每个键的值深度相等 if (typeof a === 'object' && typeof b === 'object') { const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; return keysA.every(key => keysB.includes(key) && isEqual(a[key], b[key])); } // 不同类型或无法匹配的情况 return false; }; // 遍历新对象的键,筛选出差异项 for (const key in newObj) { if (!(key in oldObj) || !isEqual(oldObj[key], newObj[key])) { diff[key] = newObj[key]; } } return diff; }
关键改进点
- 深度对比逻辑:通过
isEqual辅助函数递归检查嵌套对象和数组的内容,而非仅对比引用 - 数组处理:先校验长度,再用
every遍历每个元素做深度对比 - 对象处理:先校验键的数量与集合,再逐个键做值的深度对比
- 边界覆盖:处理了
null、undefined及不同类型值的对比场景
测试验证
// 测试用含嵌套数组的对象 const targetObj = { nome: "Camiseta Premium", imagens: [{ id: 1, url: "camiseta-front.jpg" }, { id: 2, url: "camiseta-back.jpg" }], lotes: [{ numero: "L001", quantidade: 50 }, { numero: "L002", quantidade: 100 }] }; // 对比对象自身,应返回空对象(无差异) console.log(getNew(targetObj, targetObj)); // 输出:{}
内容的提问来源于stack exchange,提问作者Nilton Schumacher F
相关产品推荐
相关产品推荐

