type
status
date
slug
summary
tags
category
icon
password
上次编辑时间
Apr 9, 2025 02:08 PM
在JavaScript中,我们处理有关对象的业务逻辑的时候,你可能见过这种奇怪的现象:

即使两个不同的对象可以具有相同的属性,但在使用
==
或===
进行比较时,它们不被认为是相等的。这是因为它们是通过引用(内存中的位置)进行比较的,而不是按值进行比较的原始值。为了测试两个对象在结构上是否相等,需要一个辅助函数。它将遍历每个对象的自身属性,以测试它们是否具有相同的值,包括嵌套对象。
可选地,对象的原型也可以通过传递true作为第三个参数来测试等价性。
function isDeepEqual(obj1,obj2, testPrototypes = false) { // 如果两者类型不同,直接返回false if (Object.prototype.toString.call(obj1) !== Object.prototype.toString.call(obj2)) { return false } // 如果两者的值和类型都相等,直接返回true if (obj1 === obj2) { return true } // 如果两者都是函数则判断其转化为字符串后的值是否相等 if (typeof obj1 === 'function' && typeof obj2 === 'function') { return obj.toString() === obj2.toString() } // 如果两者都是时间类型,则判断其毫秒值是否相等 if (obj1 instanceof Date && obj1 instanceof Date) { return obj1.getTime() === obj2.getTime() } // 在其他情况下如果两者有一个不是对象则返回false(此时两者类型相同,判断一个就行) if (typeof obj1 !== 'object') { return false } const prototypesAreEqual = testPrototypes ? isDeepEqual( Object.getPrototypeOf(obj1), Object.getPrototypeOf(obj2), true ) : true // 其他对象(数组等) const obj1Props = Object.getOwnProperties(obj1) const obj2Props = Object.getOwnProperties(obj2) return ( // 判断其属性长度是否相等 obj1Props.length === obj2Props.length && prototypesAreEqual && // 如果其属性也是对象,递归调用自身继续判断他们对应属性是否相等 obj1Props.every(prop => isDeepEqual(obj1[prop], obj2[prop])) ) }
注意:理论上此方法可以任意数据结构,但是建议用于测试普通对象、数组、函数、日期。
- 作者:Tsing
- 链接:https://www.huqing.site/front-end/1cb94e5f-a0ad-8045-a84f-f78ad3c11f5c
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。