首页 > 其他分享 >如何判断两个对象相等?

如何判断两个对象相等?

时间:2024-12-06 09:11:37浏览次数:6  
标签:obj1 obj2 相等 const 对象 判断 比较

在前端开发中,判断两个对象是否相等是一个常见的问题,但它比判断原始类型(如数字、字符串、布尔值)要复杂一些。 "相等" 的含义也取决于你的具体需求:你是要判断它们的值是否相等(浅比较和深比较),还是判断它们是否指向同一个内存地址(严格相等)。

以下是几种常用的方法:

1. 严格相等 (===)

  • 原理: === 运算符比较两个对象的内存地址。如果两个变量指向同一个对象,则返回 true,否则返回 false
  • 适用场景: 判断两个变量是否引用同一个对象。
  • 局限性: 无法判断两个不同的对象是否具有相同的值。
const obj1 = { a: 1 };
const obj2 = obj1;
const obj3 = { a: 1 };

console.log(obj1 === obj2); // true  (指向同一个对象)
console.log(obj1 === obj3); // false (不同的对象,即使值相同)

2. 浅比较 (Shallow Comparison)

  • 原理: 逐个比较对象的自身属性值。如果所有自身属性的值都相等,则认为两个对象相等。
  • 适用场景: 当对象结构简单,且你只关心对象自身属性值是否相等时。
  • 局限性: 不比较继承的属性,也不进行深层嵌套对象的比较。如果属性值是对象,则只比较它们的引用,而不是它们的值。
const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };
const obj3 = { a: 1, b: { c: 3 } };
const obj4 = { a: 1, b: { c: 3 } };

function shallowEqual(obj1, obj2) {
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);

  if (keys1.length !== keys2.length) {
    return false;
  }

  for (let key of keys1) {
    if (obj1[key] !== obj2[key]) {
      return false;
    }
  }

  return true;
}

console.log(shallowEqual(obj1, obj2)); // true
console.log(shallowEqual(obj3, obj4)); // false (因为b属性的值是不同的对象)

3. 深比较 (Deep Comparison)

  • 原理: 递归地比较所有嵌套对象的属性值。
  • 适用场景: 需要比较复杂嵌套对象的完整值时。
  • 局限性: 实现较为复杂,性能开销较大,循环引用会导致栈溢出。需要考虑如何处理循环引用以及日期、正则表达式等特殊类型。

可以使用一些库来实现深比较,例如:

  • Lodash 的 _.isEqual: 一个功能强大且经过良好测试的深比较函数。
  • Underscore.js 的 _.isEqual: 类似于 Lodash 的 _.isEqual
  • fast-deep-equal: 一个专注于性能的深比较库。
import isEqual from 'lodash.isequal'; // 使用 Lodash

const obj3 = { a: 1, b: { c: 3 } };
const obj4 = { a: 1, b: { c: 3 } };

console.log(isEqual(obj3, obj4)); // true (Lodash 的深比较)

选择哪种方法?

选择哪种方法取决于你的具体需求:

  • 比较对象引用:使用 ===
  • 比较简单对象的自身属性值:使用浅比较或手动实现一个简单的浅比较函数。
  • 比较复杂嵌套对象的完整值:使用 Lodash 的 _.isEqual 或其他深比较库。

记住,深比较的性能开销较大,因此在处理大型对象或频繁比较时,需要权衡性能和准确性。 如果可能,尽量简化对象结构或使用浅比较来提高性能。

标签:obj1,obj2,相等,const,对象,判断,比较
From: https://www.cnblogs.com/ai888/p/18589854

相关文章

  • 一个js文件导出一个new class实例,其他多个地方import引用的是同一个实例对象吗
    在JavaScript中,当你从一个模块导出一个类的实例时,其他模块在导入这个实例时将获得该实例的一个引用。这意味着,如果你修改了这个实例的属性或调用它的方法,所有导入该实例的模块都会看到这些更改,因为它们引用的是同一个对象。以下是一个示例:moduleA.js:classMyClass{const......
  • C++中对象的初始化和清理
    一、.初始化:对象的初始化使用构造函数构造函数构造函数:主要作用在于创造对时为对象的成员属性(成员变量)赋值,构造函数由编译器自动调用,无需手动调用语法:类名(){}1.构造函数没有返回值,函数名前也不用写void2.函数名与类名相同3.构造函数可以有参数,因此可以发生重载4.程序在......
  • mybatis Integer字段值传0,判断不等于空字符串,识别成空字符串排查解决
    mybatisInteger字段值传0,判断不等于空字符串,识别成空字符串排查解决根本原因:mybatis将传入的Integer类型的0被识别成空字符串在mbatis中使用Xml配置sql语句时,出现了这样一个问题。入的参数为0去做判断时,mybatis会把参数0当成是空字符串去判断而引起查询结果错误。insertinto......
  • C++对象模型实践探索
    前言C++对象模型是个常见、且复杂的话题,本文基于ItaniumC++ABI通过程序实践介绍了几种简单C++继承场景下对象模型,尤其是存在虚函数的场景,并通过图的方式直观表达内存布局。本文展示的程序构建环境为Ubuntu,glibc2.24,gcc6.3.0。由于clang和gcc编译器都是基于ItaniumC++......
  • 手把手教你从头编写 PDF – 第 6 部分:路径对象
    上一篇:手把手教你从头编写PDF–第5部分:Helloworld在第四部分中我曾提到,PDF是通过加载一系列命令(存放在流对象中)绘制出来的。通过这些命令,PDF查看器可以解析如何绘制页面上所有的内容。在本文中,我将探索图形命令,并通过文本编辑器创建一个PDF,让它在页面上画几条线。在......
  • JMeter 5.4.1 if控制器使用(注册一个会员,判断注册成功过后登录)
    1、线程组结构2、参数化的形式,使用函数助手随机生成用户名和email3、正则表达式匹配注册响应结果(正则表达式提取器在请求里面的后置处理器中添加),可以添加一个debug,方便查看匹配到的内容4、if控制器的写法,然后在if控制器下面去添加满足条件后要执行的请求......
  • 【Spring 全家桶】 Spring IOC & DI 保姆式教学, 教你不用new也能获取到对象的依赖注入
    本篇会加入个人的所谓鱼式疯言❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言而是理解过并总结出来通俗易懂的大白话,小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.......
  • ​‌Spring Boot中的@GetMapping注解可以用于处理HTTP GET请求,并且可以接收对象参数​
    下面内容来自Ai回答,经过亲自验证,正确 ‌SpringBoot中的@GetMapping注解可以用于处理HTTPGET请求,并且可以接收对象参数。‌接收对象参数的基本方式在SpringBoot中,可以通过@GetMapping注解接收对象参数,这通常通过@RequestParam或@RequestBody注解来实现。‌使用@Reque......
  • 【资金流入强度】资金多空操作方向判断以及强弱多线操作信号,通达信炒股软件指标
    如上图,副图指标【资金流入强度】,一条红绿变色资金强弱线,红色时多头主导,绿色时空头资金主导。蓝色柱线短线参考做多信号以及短线能量强弱信号。如上图,指标中有两个关键位置,零轴多空分界线,紫色虚线15参考资金流入强势分档线。在资金强弱线从下往上突破零轴,进入资金做多阶段,在......
  • 获取到的值不为空,存入对象属性时,报空指针错误
    publicTenantAccessTokentenantAccessToken;/***获取token*@return*/@OverridepublicTenantAccessTokengetTenantAccessToken(){if(tenantAccessToken==null||tenantAccessToken.getTenantAccessTok......