原生JS比较两个对象的值相等


前两天需要用到对比两个对象值相等的功能,习惯性打开lodash寻找isEqual方法,但不知为何中文文档死活打不开。偷懒直接用stringify来对比吧,又可能因为顺序问题不能正确判断。索性自我练习一下,写个对比对象的方法好了。~~
问就是上班摸鱼~~

思路

为了节省性能,遇到不需要判断的情况可以直接返回,如类型不是对象、引用地址相同、有一个为null、键值数量不同

排除以上情况后再进行值判断,自然用到循环遍历的方式依次判断,有一个不同直接返回false

但如果,某个键值也是对象呢,似乎就要用到递归处理了

解决方案

话不多说,直接放代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 校验对象是否相等方法
function isEqualObj(a, b) {
// 当传入类型不是object时,抛出错误
if (!(a instanceof Object && b instanceof Object)) {
throw new Error('传入类型错误')
}
// 引用地址相同时,直接返回true(此时包含两者为null的情况)
if (a === b) {
return true
}
// 有一个为null时
if (a === null || b === null) {
return false
}

// 获取a和b的全部键值
const aProps = Object.keys(a)
const bProps = Object.keys(b)
// 属性数量不同时
if (aProps.length !== bProps.length) {
return false
}
// 遍历查看属性值是否相等
for (let i = 0; i < aProps.length; i++) {
const propName = aProps[i]
// 判断b是否存在a的这个属性
if (!Object.prototype.hasOwnProperty.call(b, propName)) {
return false
}
const propA = a[propName]
const propB = b[propName]
// 当属性值为对象时,递归判断
if (propA instanceof Object && propB instanceof Object) {
if (!isEqualObj(propA, propB)) {
return false
}
} else if (propA !== propB) {
return false
}
}
return true
}

问题

以上代码其实依然有问题,那就是当对象属性为函数时,判断会失败。不过我的需求暂时不会出现这种情况,以后再说啊哈哈。

而且,这不是有万能的lodash嘛(不愧是我)