当前位置:首页 > 编程知识 > 正文

JavaScript中如何判断两个对象是否相等

一、基础概念

1、在JavaScript中,对象是一组键值对的集合,每个键对应一个值,值可以是任何JavaScript数据类型,包括另一个对象、数组或函数。

2、对象之间的比较是按引用比较的,也就是说,只有当两个对象引用同一个对象时才相等。而如果两个对象具有相同的键值对,并且这些键值对的值也相等,这时候这两个对象是不相等的。

3、在JavaScript中,原始类型的比较是按值比较的,因此,原始类型的值相等时,它们也被认为相等。

二、深度比较两个对象

1、在JavaScript中怎样可以判断两个对象是否相等呢?

2、如果想要深度比较两个对象,需要使用递归的方式遍历对象的每个键值对,对于值是对象或者数组的,需要继续递归比较,直到比较到原始类型的值,然后再进行比较。

function deepEqual(x, y) {
  if (x === y) {
    return true;
  } else if (
    typeof x == "object" && x != null &&
    typeof y == "object" && y != null
  ) {
    if (Object.keys(x).length !== Object.keys(y).length) {
      return false;
    }
    for (let prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqual(x[prop], y[prop])) {
          return false;
        }
      } else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
}

三、快速比较两个对象

1、如果只是简单地比较两个对象是否具有相同的键值对,又想快速、简便地实现,可以使用JSON.stringify()方法将对象序列化为JSON字符串,然后比较字符串是否相等。

2、但是,注意,这种方法只对不包含函数、undefined、Symbol等非序列化类型的对象比较有效。

function quickEqual(x, y) {
  return JSON.stringify(x) === JSON.stringify(y);
}

四、其他注意事项

1、在深度比较两个对象时,要注意对象本身循环引用的情况,需要使用一个Set“已比较”的集合来保存已经比较过的对象,防止发生死循环。

function deepEqualWithCircularReference(x, y, seen = new Set()) {
  if (x === y) {
    return true;
  } else if (
    typeof x == "object" && x != null &&
    typeof y == "object" && y != null
  ) {
    if (seen.has(x) || seen.has(y)) {
      return true;
    }
    seen.add(x);
    seen.add(y);
    if (Object.keys(x).length !== Object.keys(y).length) {
      return false;
    }
    for (let prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!deepEqualWithCircularReference(x[prop], y[prop], seen)) {
          return false;
        }
      } else {
        return false;
      }
    }
    return true;
  } else {
    return false;
  }
}

2、对于大型或复杂的对象,比较时可能会耗费大量的资源和时间,所以可以在比较之前,先比较两个对象的类型和基本属性,如果不同,直接返回false。

function typeAndPropEqual(x, y) {
  if (typeof x !== typeof y) {
    return false;
  } else if (typeof x == "object" && x != null &&
             typeof y == "object" && y != null) {
    if (Object.keys(x).length !== Object.keys(y).length) {
      return false;
    }
    for (let prop in x) {
      if (y.hasOwnProperty(prop)) {
        if (!typeAndPropEqual(x[prop], y[prop])) {
          return false;
        }
      } else {
        return false;
      }
    }
    return true;
  } else {
    return x === y;
  }
}

五、总结

本文介绍了JavaScript中如何比较两个对象是否相等,包括深度比较和快速比较两种方法,并讨论了避免循环引用和比较大型对象的注意事项。