一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

JavaScript 中通过 hasOwnProperty 实现简单的对象深度对比

时间:2026-07-09 12:43:47 编辑:袖梨 来源:一聚教程网

hasOwnProperty 无法实现真正的深度对比,因其仅判断属性是否为对象自有,不比较值、不递归、不处理嵌套结构;它在深度对比中的核心作用是过滤继承属性,避免原型方法干扰,常与递归和类型判断结合使用。

直接用 hasOwnProperty 无法实现真正的深度对比,它只判断对象自身是否拥有某个属性(不查原型链),但可以作为深度对比中“属性存在性检查”的一个基础工具。要实现简单可靠的深度对比,需结合递归、类型判断和 hasOwnProperty 排除继承属性干扰。

为什么不能只靠 hasOwnProperty?

hasOwnProperty 只回答“这个 key 是不是对象自己定义的”,不比较值、不递归、不处理数组或嵌套对象。比如两个结构相同但属性来自原型的对象,hasOwnProperty 结果一样,但实际内容可能不同。

用 hasOwnProperty 过滤掉继承属性

在遍历对象时,必须跳过原型上的属性,否则会把 toStringvalueOf 等方法也纳入对比,导致误判。这是 hasOwnProperty 在深度对比中最关键的作用:

  • 遍历对象所有 key 时,先用 obj.hasOwnProperty(key) 确保该 key 属于实例本身
  • 忽略 for...in 默认包含的原型属性
  • 避免因原型链污染或扩展导致的对比错误

基础深度对比函数(含 hasOwnProperty)

以下是一个轻量、可读性强的实现,支持普通对象和原始值,使用 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 场景)

如果选择用 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 等类型的单独处理,否则它们会被当作普通对象递归,结果可能不符合预期。

热门栏目