js实现一个深比较 isEquals

前沿

在前端我们比较两个值是否相等一般都是使用==,===,如有在比较对象的时候,会遍历这个对象的key,然后拿到key所对应的value,然后去比较两个对象key所对应的value是否相等。 数组也是同样道理,遍历比较就可了。

  • 例如:
javascript 复制代码
const obj = {key:1, value:1}
const obj1 = {key:1, value:1}

obj === obj1  // fasle
isEqual(obj, obj1)  // true,因为虽然对象的引用地址不同,但是对象key所对应的value是相同的。

const isEquals = (obj, otherObj) => {
    for(let key in obj){
        if(key in otherObj){
            return obj[key] === otherObj[key]
        } else {
            return false
        }
    }
    
    for(let key in otherObj){
        if(key in obj){
            return obj[key] === otherObj[key]
        }else {
            return false
        }
    }
    return true
}

上面我们实现了一个简单的isEquals方法,我们只对对象的一层进行比较。如果让我们实现一个对象深层次的比较,该如实现呢?

实现

有这样两个深层次的对象,如下:

css 复制代码
const obj1 = {
    key:1,
    name:"jack",
    value: { name: 'jack', value: 1},
    arr: [1, 2, 3],
    innerArr: [1,2, { name: 'tom', value: 1 }]
}

const obj2 = {
    key:1,
    name:"jack",
    value: { name: 'jack', value: 1},
    arr: [1, 2, 3],
    innerArr: [1,2, { name: 'tom', value: 1 }]
}

const obj3 = {
    key:1,
    name:"jack",
    value: { name: 'jack', value: 2},
    arr: [1, 2, 3],
    innerArr: [1,2, { name: 'tom', value: 3 }]
}
  • 上面三个对象,obj1obj2是相同的,obj1obj3valueinnerArr[2].value是不同的
  • 所以isEquals(obj1, obj2) === true,isEquals(obj1, obj3) === false

实现

我们还是沿用上面写的isEquals,只不过在比较的时候,如果发现两个不相等,那么我们只需要递归调用就可以了,然后在添加下处理基本数据类型的条件就可以啦。实现如下:

vbnet 复制代码
const isEqusls = (obj, otherObj) => {
  // 如果是 null 或 undefined,在这里判断
  if (obj == null || otherObj == null) {
    return obj === otherObj
  }
  // number boolean function string 在这里判断
  if (typeof obj !== 'object' || typeof otherObj !== 'object') {
    return obj === otherObj
  }
  
  // 如果是引用数据类型,那么遍历进行比较
  for (let key in obj) {
    if (!(key in otherObj)) {
      return false
    }
  }

  for (let key in otherObj) {
    if (!(key in otherObj)) {
      return false
    }
    const value = obj[key]
    const otherValue = otherObj[key]
    if (value !== otherValue) {
      // 如果递归的时候返回了 false , 那么我们 return false,
      // 如果返回时 true, 那么那么继续遍历比较
      let flag = isEqusl(value, otherValue)
      if(!flag) return false
    }
  }
  return true
}
相关推荐
bearpping17 分钟前
Nginx 配置:alias 和 root 的区别
前端·javascript·nginx
@大迁世界39 分钟前
07.React 中的 createRoot 方法是什么?它具体如何运作?
前端·javascript·react.js·前端框架·ecmascript
January12071 小时前
VBen Admin Select 选择框选中后仍然显示校验错误提示的解决方案
前端·vben
. . . . .1 小时前
前端测试框架:Vitest
前端
xiaotao1311 小时前
什么是 Tailwind CSS
前端·css·css3
颜酱2 小时前
DFS 岛屿系列题全解析
javascript·后端·算法
战南诚2 小时前
VUE中,keep-alive组件与钩子函数的生命周期
前端·vue.js
发现一只大呆瓜2 小时前
React-彻底搞懂 Redux:从单向数据流到 useReducer 的终极抉择
前端·react.js·面试
霍理迪3 小时前
Vue的响应式和生命周期
前端·javascript·vue.js