Appearance
deepEqual 深度相等比较
用于深度比较两个值是否相等。支持:原始类型(含 NaN)、数组、普通对象、Date、RegExp、Map、Set、ArrayBuffer、DataView、TypedArray、Error 等;并处理循环引用。
安装与引入
按需导入(推荐)
ts
import { deepEqual } from '@cuixingjian/cui-utils'子路径导入
ts
import { deepEqual } from '@cuixingjian/cui-utils/deepEqual'使用示例
基础类型比较
ts
import { deepEqual } from '@cuixingjian/cui-utils/deepEqual'
// 原始类型
deepEqual(1, 1) // true
deepEqual(NaN, NaN) // true
deepEqual(0, -0) // true(本实现认为 +0 与 -0 相等)
// 对象与数组
deepEqual({ a: 1, b: [1, 2] }, { a: 1, b: [1, 2] }) // true
deepEqual([{ x: 1 }], [{ x: 1 }]) // true
// Date / RegExp
deepEqual(new Date('2020-01-01'), new Date('2020-01-01')) // true
deepEqual(/abc/gi, /abc/gi) // true
// Map / Set(无序比较)
const m1 = new Map([[{ k: 1 }, { v: 1 }], ['x', 2]])
const m2 = new Map([['x', 2], [{ k: 1 }, { v: 1 }]])
deepEqual(m1, m2) // true
const s1 = new Set([{ a: 1 }, 2])
const s2 = new Set([2, { a: 1 }])
deepEqual(s1, s2) // true
// TypedArray / ArrayBuffer / DataView
deepEqual(new Uint8Array([1, 2]), new Uint8Array([1, 2])) // true
// 循环引用
const a: any = { self: null }
const b: any = { self: null }
a.self = a; b.self = b
deepEqual(a, b) // trueAPI 说明
函数签名
ts
function deepEqual(a: any, b: any): boolean参数
| 参数名 | 类型 | 说明 |
|---|---|---|
| a | any | 第一个比较值 |
| b | any | 第二个比较值 |
返回值
返回 boolean,表示两个值是否深度相等。
注意事项
相等规则
- 原始类型:使用
===比较,但NaN与NaN视为相等 - +0 与 -0:默认视为相等
- 引用类型:递归比较内部结构
特殊类型处理
- Date:比较时间戳
- RegExp:比较 source 和 flags
- Map/Set:不依赖元素顺序,会匹配对应项(大集合时性能开销较大)
- ArrayBuffer/DataView/TypedArray:按字节或元素逐一比较
- Error:比较 name 和 message
- 函数/Promise/Symbol/WeakMap/WeakSet:按引用相等比较
循环引用
使用 WeakMap 跟踪已比较的对象,避免无限递归。
典型场景
- 单元测试:验证复杂对象是否相等
- 状态比较:检测状态是否发生变化
- 表单验证:比较表单数据与初始值
- 缓存判断:判断数据是否需要更新
源码
展开查看
ts
// 源码来自 @cuixingjian/cui-utils/deepEqual
export function deepEqual(a: any, b: any): boolean {
if (a === b) {
return a !== 0 || 1 / a === 1 / b
}
if (Number.isNaN(a) && Number.isNaN(b)) return true
const typeA = typeof a
const typeB = typeof b
if (typeA !== 'object' || a === null) return false
if (typeB !== 'object' || b === null) return false
const seenA = new WeakMap<object, object>()
const seenB = new WeakMap<object, object>()
return equalObject(a, b, seenA, seenB)
}
// ...(其余实现见源码文件)