hasOwnProperty 无法实现真正的深度对比,因其仅判断属性是否为对象自有,不比较值、不递归、不处理嵌套结构;它在深度对比中的核心作用是过滤继承属性,避免原型方法干扰,常与递归和类型判断结合使用。
直接用 hasOwnProperty 无法实现真正的深度对比,它只判断对象自身是否拥有某个属性(不查原型链),但可以作为深度对比中“属性存在性检查”的一个基础工具。要实现简单可靠的深度对比,需结合递归、类型判断和 hasOwnProperty 排除继承属性干扰。
hasOwnProperty 只回答“这个 key 是不是对象自己定义的”,不比较值、不递归、不处理数组或嵌套对象。比如两个结构相同但属性来自原型的对象,hasOwnProperty 结果一样,但实际内容可能不同。
在遍历对象时,必须跳过原型上的属性,否则会把 toString、valueOf 等方法也纳入对比,导致误判。这是 hasOwnProperty 在深度对比中最关键的作用:
obj.hasOwnProperty(key) 确保该 key 属于实例本身for...in 默认包含的原型属性以下是一个轻量、可读性强的实现,支持普通对象和原始值,使用 hasOwnProperty 保证只比自有属性:
立即学习“Java免费学习笔记(深入)”;
function deepEqual(a, b) { if (a === b) return true; if (a == null || b == null) return false; if (typeof a !== 'object' || typeof b !== 'object') return false; const keysA = Object.keys(a); const keysB = Object.keys(b); if (keysA.length !== keysB.length) return false; for (const key of keysA) { // 关键:确保是自有属性,排除原型干扰 if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) continue; if (!deepEqual(a[key], b[key])) return false; } return true;}
注意:Object.keys() 本身只返回自有可枚举属性,已隐含 hasOwnProperty 逻辑,所以严格来说上面的 hasOwnProperty 检查是冗余的;但显式写出能更清晰表达意图,尤其在手动用 for...in 时必不可少。
如果选择用 for...in 遍历(例如需要兼容旧环境或特殊枚举控制),hasOwnProperty 就不可省略:
for (let key in a) { if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) continue; if (!deepEqual(a[key], b[key])) return false;}
同时建议补充对数组、Date、RegExp 等类型的单独处理,否则它们会被当作普通对象递归,结果可能不符合预期。