当前位置: 首页 > article >正文

JavaScript中判断两个对象是否相同(所有属性的值是否都相同)

在JavaScript中,判断两个对象的所有属性是否相同(包括嵌套对象)需要深度比较(deep comparison)。以下是几种实现方法:


方法1:简易深度比较(不考虑循环引用、Symbol和特殊对象)

javascript

复制

下载

function deepEqual(obj1, obj2) {// 基本类型直接比较if (obj1 === obj2) return true;// 检查是否为对象且非nullif (typeof obj1 !== 'object' || obj1 === null ||typeof obj2 !== 'object' || obj2 === null) {return false;}// 比较构造函数类型if (obj1.constructor !== obj2.constructor) return false;// 获取对象的键(仅自身可枚举属性)const keys1 = Object.keys(obj1);const keys2 = Object.keys(obj2);// 键数量不同则不等if (keys1.length !== keys2.length) return false;// 递归比较每个键的值for (const key of keys1) {if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {return false;}}return true;
}

方法2:完整深度比较(支持循环引用、Symbol和特殊对象)

javascript

复制

下载

function deepEqual(obj1, obj2, visited = new WeakMap()) {// 基本类型直接比较if (obj1 === obj2) return true;// 检查是否为对象且非nullif (typeof obj1 !== 'object' || obj1 === null ||typeof obj2 !== 'object' || obj2 === null) {return false;}// 处理循环引用if (visited.has(obj1) {return visited.get(obj1) === obj2;}visited.set(obj1, obj2);// 比较构造函数类型if (obj1.constructor !== obj2.constructor) return false;// 特殊对象处理if (obj1 instanceof Date) return obj1.getTime() === obj2.getTime();if (obj1 instanceof RegExp) return obj1.toString() === obj2.toString();// 获取所有键(包括Symbol和自身可枚举属性)const keys1 = Reflect.ownKeys(obj1);const keys2 = Reflect.ownKeys(obj2);// 键数量不同则不等if (keys1.length !== keys2.length) return false;// 递归比较每个键的值for (const key of keys1) {if (!Reflect.has(obj2, key) ||!deepEqual(obj1[key], obj2[key], visited)) {return false;}}return true;
}

关键点说明

  1. 深度递归

    • 逐层比较嵌套对象的属性值。

    • 使用递归处理嵌套结构。

  2. 循环引用处理

    • 通过 WeakMap 记录已比较对象,避免无限递归。

    • 当检测到循环引用时直接比较引用是否相同。

  3. 特殊对象支持

    • Date:比较时间戳。

    • RegExp:比较正则表达式的字符串形式。

    • Array:自动支持(数组也是对象)。

  4. 键类型支持

    • 使用 Reflect.ownKeys() 获取所有自身键(包括Symbol)。

    • 使用 Object.keys() 仅获取可枚举字符串键(简易版)。

  5. 严格检查

    • 比较构造函数确保类型一致(如 Array vs Object)。

    • 键数量不等时快速失败。


使用示例

javascript

复制

下载

const objA = { a: 1, b: { c: 2 }, d: [3, 4] };
const objB = { a: 1, b: { c: 2 }, d: [3, 4] };
const objC = { a: 1, b: { c: 99 } };console.log(deepEqual(objA, objB)); // true
console.log(deepEqual(objA, objC)); // false

注意事项

  • 性能:深度比较可能较慢,避免在大型对象上使用。

  • 特殊对象:如需支持 Set/Map 等,需额外扩展。

  • 函数属性:函数按引用比较(通常不比较函数体)。

  • 库推荐:复杂场景建议使用 Lodash 的 _.isEqual()

javascript

复制

下载

// 使用 Lodash 的深度比较
import _ from 'lodash';
console.log(_.isEqual(objA, objB)); // true
http://www.lryc.cn/news/2400730.html

相关文章:

  • Flask 应用的生产环境部署指南
  • 思科设备网络实验
  • Oracle OCP与MySQL OCP认证如何选?
  • AWS之数据分析
  • C# Onnx 动漫人物头部检测
  • 【Ragflow】24.Ragflow-plus开发日志:增加分词逻辑,修复关键词检索失效问题
  • gin 常见中间件配置
  • 蚂蚁森林自动收能量助手:Ant_Forest_1_5_4_3绿色行动新选择
  • Zookeeper 集群部署与故障转移
  • Redis最佳实践——电商应用的性能监控与告警体系设计详解
  • 区域徘徊检测算法AI智能分析网关V4助力公共场所/工厂等多场景安全升级
  • 修复与升级suse linux
  • 电力高空作业安全检测(2)数据集构建
  • 嵌入式开发之STM32学习笔记day18
  • [论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning
  • 一键 Ubuntu、Debian、Centos 换源(阿里源、腾讯源等)
  • 汽车安全:功能安全FuSa、预期功能安全SOTIF与网络安全Cybersecurity 解析
  • 【C++高级主题】虚继承
  • 基于 ZYNQ 的实时运动目标检测系统设计
  • 数据结构(JAVA版)练习题
  • C#编程过程中变量用中文有啥影响?
  • 哈希表入门:用 C 语言实现简单哈希表(开放寻址法解决冲突)
  • [华为eNSP] 在eNSP上实现IPv4地址以及IPv4静态路由的配置
  • 2024年第十五届蓝桥杯青少组c++国赛真题——快速分解质因数
  • 【动手学MCP从0到1】2.1 SDK介绍和第一个MCP创建的步骤详解
  • 基于MyBatis插件实现动态表名解决多环境单一数据库问题
  • 测试面试题总结一
  • Spring Boot应用多环境打包与Shell自动化部署实践
  • 【深度学习】14. DL在CV中的应用章:目标检测: R-CNN, Fast R-CNN, Faster R-CNN, MASK R-CNN
  • grpc的二进制序列化与http的文本协议对比