JavaScript自定义深度相等函数deeplyEquals运行返回结果异常排查
问题排查
你当前实现的核心问题有以下几点:
- 递归调用的返回值完全未被捕获处理:你调用
deeplyEquals对比序列化后的对象内容,但比对结果没有用于修改当前层级的计数,对象内容的差异不会被统计到最终结果中。 - 局部计数器无法跨层级共享:每次递归调用都会生成新的独立
counter变量,不同层级的计数完全不互通,就是你观测到计数器异常变动的核心原因。 - 没有处理非数组入参的场景:你递归时传入的是
JSON.stringify生成的字符串,字符串的length是字符长度,循环会遍历每个字符进行比对,这就是测试时计数器一度涨到7的原因,但这部分比对结果完全没有传递到上层函数。 - 缺少基础边界校验:没有判断两个数组长度是否一致,也没有处理入参为普通对象、原始值的场景。
- 依赖
JSON.stringify做对象比对本身存在缺陷:如果对象包含undefined、函数、Symbol类型属性,或者属性顺序不同,都会出现误判。
修复方案
这里直接放弃计数器的实现思路,遇到不等的情况直接返回false,所有内容比对通过才返回true,逻辑更简洁也不会出现计数不通的问题:
const deeplyEquals = (val1, val2) => { // 类型不同直接返回不等 if (typeof val1 !== typeof val2) return false; // 处理原始类型与null if (typeof val1 !== 'object' || val1 === null || val2 === null) { return val1 === val2; } // 处理数组比对 if (Array.isArray(val1) && Array.isArray(val2)) { if (val1.length !== val2.length) return false; for (let i = 0; i < val1.length; i++) { if (!deeplyEquals(val1[i], val2[i])) return false; } return true; } // 处理普通对象比对 const keys1 = Object.keys(val1); const keys2 = Object.keys(val2); if (keys1.length !== keys2.length) return false; for (const key of keys1) { if (!keys2.includes(key) || !deeplyEquals(val1[key], val2[key])) return false; } return true; };
测试你给出的用例:
console.log(deeplyEquals([1, 2, { a: "hello" }], [1, 2, { a: "bye" }])); // 输出 false
符合预期结果。
内容的提问来源于stack exchange,提问作者ajnabz
相关产品推荐
相关产品推荐

