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
}
相关推荐
To_OC3 小时前
面试被问了三回三栏布局,这次我终于把 BFC 那层窗户纸捅破了
前端·css·面试
To_OC3 小时前
啃完 TS 工具类型我发现:Pick 和 Omit 原来就是一层窗户纸
前端·面试·typescript
风月说与山鬼4 小时前
三、大括号语法
前端·react.js
kyriewen5 小时前
我把最常踩的8个CORS跨域报错整理了一遍——第8个去年还不存在
前端·javascript
Csvn5 小时前
🕰️ 闭包 + setTimeout 的 5 个经典陷阱:为什么定时器看到的永远不是最新的值?
前端
lilian2336 小时前
Harmony os 技术实战|拼豆制图27:用单字符编码承载 50 张 70×70 图纸
前端·数据库·华为·harmonyos
CarIise6 小时前
CSS选择器与样式关联
前端·css·tensorflow
里欧跑得慢7 小时前
CSS 模块化架构的演进:BEM、CSS Modules 到 CSS-in-JS 的反思
前端·css·flutter·web·css-in-js
IT_陈寒7 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端