JavaScript怎么判断两个对象相等

该文章已生成可运行项目,

1.严格相等运算符 (===)

使用 === 运算符可以比较两个对象是否引用同一个对象。如果两个变量引用了同一个对象,则它们是相等的,否则它们是不相等的。例如:

const obj1 = { a: 1 };
const obj2 = { a: 1 };
const obj3 = obj1;

console.log(obj1 === obj2); // false
console.log(obj1 === obj3); // true

2.使用Lodash等工具库判断两个对象是否相等

可以使用 Lodash 的 isEqual 方法(依然不比较引用地址)。 isEqual 方法会递归比较两个对象的属性值是否相等,包括嵌套对象和数组。

const obj1 = { a: 1, b: { c: 2 } };
const obj2 = { a: 1, b: { c: 2 } };
const obj3 = { a: 1, b: { c: 123 } };

console.log(_.isEqual(obj1, obj2)); // true
console.log(_.isEqual(obj1, obj3)); // false

但这种方法不能比较原型:

let obj1 = {
  a: 1,
  b: {
    c: {
      d: [1, 2, 3],
    },
  },
  __proto__: {
    e: 12,
  },
};
let obj2 = {
  a: 1,
  b: {
    c: {
      d: [1, 2, 3],
    },
  },
  __proto__: {
    e: 11,
  },
};
console.log(_.isEqual(obj1, obj2));//true实际上二者的e属性值并不相等

3.JSON.stringify方法

如果你的对象中只包含简单类型(如数字、字符串、布尔值和 null)以及其他对象或数组,则可以使用 JSON.stringify 方法将对象转换为字符串,然后比较这些字符串(还是不比较引用地址)。例如:

const obj1 = { a: 1, b: "hello", c: true };
const obj2 = { a: 1, b: "hello", c: true };
const obj3 = { a: 1, b: "aaa", c: true };

console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true
console.log(JSON.stringify(obj1) === JSON.stringify(obj3)); // false

在上面的例子中, JSON.stringify(obj1)JSON.stringify(obj2)都返回相同的字符串,因此它们的比较返回 true 。而JSON.stringify(obj1)JSON.stringify(obj3)返回不同的字符串,因此比较返回false

需要注意的是,这种方法只适用于简单类型和嵌套对象或数组,因为它无法处理对象中包含函数、正则表达式和 Date 等类型的情况。

4.使用Object.is()方法

它与运算符类似,但是有一些特殊情况,例如Object.is(+0, -0)返回 false ,而===运算符返回true

const obj1 = { a: 1 };
const obj2 = { a: 1 };
const obj3 = obj1;

console.log(Object.is(obj1, obj2)); // false
console.log(Object.is(obj1, obj3)); // true

let a = +0;
let b = -0;

console.log(Object.is(a, b)); //false

5.手写代码

如果你只是需要比较两个对象的属性是否相等(不比较引用地址),你可以使用循环或 Object.keys 方法来获取对象属性的列表,并比较它们的值。

先来说一下思路:

  • 判断两个对象是否指向同一内存
  • 使用 Object.getOwnPropertyNames 获取对象所有键名数组
  • 判断两个对象的键名数组是否相等
  • 遍历键名,判断键值是否都相等
function isObjectValueEqual(a, b) {
  // 判断两个对象是否指向同一内存,指向同一内存返回 true
  if (a === b) return true;
  // 获取两个对象键值数组
  let aProps = Object.getOwnPropertyNames(a);
  let bProps = Object.getOwnPropertyNames(b);
  // 判断两个对象键值数组长度是否一致,不一致返回 false
  if (aProps.length !== bProps.length) return false;
  // 遍历对象的键值
  for (let prop in a) {
    // 判断 a 的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回 false
    if (typeof a[prop] === "object") {
      if (!isObjectValueEqual(a[prop], b[prop])) return false;
    } else if (a[prop] !== b[prop]) {
      return false;
    }
  }
  return true;
}

测试一下:


function isObjectValueEqual(a, b) {
  // 判断两个对象是否指向同一内存,指向同一内存返回 true
  if (a === b) return true;
  // 获取两个对象键值数组
  let aProps = Object.getOwnPropertyNames(a);
  let bProps = Object.getOwnPropertyNames(b);
  // 判断两个对象键值数组长度是否一致,不一致返回 false
  if (aProps.length !== bProps.length) return false;
  // 遍历对象的键值
  for (let prop in a) {
    // 判断 a 的键值,在 b 中是否存在,不存在,返回 false
    // if (b.hasOwnProperty(prop)) {
    // 判断 a 的键值是否为对象,是则递归,不是对象直接判断键值是否相等,不相等返回 false
    if (typeof a[prop] === "object") {
      if (!isObjectValueEqual(a[prop], b[prop])) return false;
    } else if (a[prop] !== b[prop]) {
      return false;
    }
    // } else {
    //   return false;
    // }
  }
  return true;
}

let obj1 = {
  a: 1,
  b: {
    c: {
      d: [1, 2, 3],
    },
  },
  __proto__: {
    e: 12,
  },
};
let obj2 = {
  a: 1,
  b: {
    c: {
      d: [1, 2, 3],
    },
  },
  __proto__: {
    e: 11,
  },
};
console.log(isObjectValueEqual(obj1, obj2));//false
本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值