如何进行深度比较JavaScript对象?

29 min read

在 JavaScript 中,对象是引用类型,因此简单的使用 ===== 运算符进行比较只会比较它们的引用是否相同。深度比较两个对象可以使用以下方法之一:

  1. JSON.stringify(): 将对象转换为 JSON 字符串后进行比较。这种方法的缺点是不能保留对象的函数、日期对象等特殊类型,同时也不能比较循环引用的情况。
const obj1 = {a: 1, b: {c: 2}}
const obj2 = {a: 1, b: {c: 2}}
console.log(JSON.stringify(obj1) === JSON.stringify(obj2)) // true
  1. 递归比较: 递归比较两个对象的每一个属性,如果属性值不同则返回 false,如果是对象类型则递归调用比较函数:
function deepEqual(obj1, obj2) {
  if (obj1 === obj2) {
    return true;
  }
  if (typeof obj1 !== "object" || typeof obj2 !== "object" || obj1 == null || obj2 == null) {
    return false;
  }
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  if (keys1.length !== keys2.length) {
    return false;
  }
  for (let key of keys1) {
    if (!keys2.includes(key) || !deepEqual(obj1[key], obj2[key])) {
      return false;
    }
  }
  return true;
}
const obj1 = {a: 1, b: {c: 2}}
const obj2 = {a: 1, b: {c: 2}}
console.log(deepEqual(obj1, obj2)) // true

注意:上述方法都无法处理循环引用的情况,即一个对象引用了自己。如果需要处理这种情况,可以添加一个特殊的属性标记已经访问过的对象,从而避免进入循环。