### 在 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
* 简单值例如字符串和数字比较值就可以了
* 对象比较的时候比较的是引用(就是内存地址)