在 JavaScript 中如何比较两个对象?


### 在 JavaScript 中如何比较两个对象?

 

#### Answer

 

即使两个不同的对象拥有相同的属性和相同的值,它们使用`==`和`===`比较的时候也不会被认为是相等的。这是因为它们是通过它们的引用来比较的(也就是在内存中的地址),而与简单值不同是通过值得比较。

 

为了测试是否两个对象在结构上是一样的,需要一个助手函数。它会遍历每一个对象的自身属性去测试是否它们拥有相等的值,包含了嵌套对象。

 

可选的,对象的prototype也可以被测试是否相等通过传递第三个参数为`true`。

 

提示:此技术只能用来测试简单对象,数组,函数,时间对象和简单值是否结构相等。
 
function isDeepEqual(obj1, obj2, testPrototypes = false) {
  if (obj1 === obj2) {//如果obj1和obj2是同一个对象,返回true
    return true
  }

  if (typeof obj1 === "function" && typeof obj2 === "function") {
    //如果obj1和obj2都是function,转换成字符串后比较
    return obj1.toString() === obj2.toString()
  }

  if (obj1 instanceof Date && obj2 instanceof Date) {
    //如果obj1和obj2都是Date实例,获取毫秒值比较
    return obj1.getTime() === obj2.getTime()
  }

  if (
    Object.prototype.toString.call(obj1) !==
      Object.prototype.toString.call(obj2) ||
    typeof obj1 !== "object"
  ) {
    return false
  }
  //如果obj1是简单类型且toString后的值不相等,直接返回false

  const prototypesAreEqual = testPrototypes
    ? isDeepEqual(
        Object.getPrototypeOf(obj1),
        Object.getPrototypeOf(obj2),
        true
      )
    : true
    //判断原型是否相等

  const obj1Props = Object.getOwnPropertyNames(obj1)
  const obj2Props = Object.getOwnPropertyNames(obj2)

  return (
    obj1Props.length === obj2Props.length &&
    prototypesAreEqual &&
    obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop]))
  )
  //obj1和obj2自身属性长度相等
  //原型相等
  //递归调用isDeepEqual判断每一个属性值是否相等
}
#### Good to hear
 
* 简单值例如字符串和数字比较值就可以了
* 对象比较的时候比较的是引用(就是内存地址)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM