zoukankan      html  css  js  c++  java
  • 判断两个对象的内容是否相等

    由于在做键盘导航组件的项目时,有这样一个需求,当用户传入按键字母和网址的映射时,如果和 localStorage 中的不一样那么就用 localStorage 中存储的,这个时候就需要比较两个对象的内容是否相等,但是在 JS 中对象是一种引用类型.

    obj1 = {
      a: 1
    }
    obj2 = {
      a: 1
    }
    console.log(obj1 === obj2) // false
    

    即使两个对象的内容完全相同,因为它们的地址不同,因此 obj1 === obj2 会返回 fasle。

    所以自己根据深拷贝时递归的思想写了一个比较两个对象之间内容是否相同的函数。

    function compareObject (obj1, obj2) {
      // 递归终止条件,当 obj1 或 obj2 不是对象时,此时就可以进行判断了
      if (typeof obj1 !== 'object' || typeof obj2 !== 'object') {
        if (obj1 === obj2) {
          return true
        } else if (obj1 !== obj2) {
          return false
        }
      }
      // 获取对象的自由属性组成的数组
      const obj1PropsArr = Object.getOwnPropertyNames(obj1)
      const obj2PropsArr = Object.getOwnPropertyNames(obj2) 
      // 如果数组的长度不相等,那么说明对象属性的个数都不同,返回 false
      if (obj1PropsArr.length !== obj2PropsArr.length) {
        return false
      }
      // 记录当前 compareObject 的返回值,默认是 true
      let status = true
      for (key of obj1PropsArr) {
        status = compareObject(obj1[key], obj2[key])
        // 关键代码,当 status 为 false 时下面就不用再进行判断了,说明两个对象的内容并不相同
        // 如果没有下面这条语句,那么只要对象底层的内容是相同的那么就返回 true
        if (!status) {
          break
        }
      }
      // 每次 compareObject 执行的返回结果
      return status
    }
    

    测试代码:

    // 判断两个对象的内容相等
    const obj1 = {
      a: 1,
      b: {
        c: 2,
        d: {
          e: 4
        }
      }
    }
    const obj2 = {
      a: 1,
      b: {
        c: 2,
        d: {
          e: 4
        }
      }
    }
    console.log(compareObject(obj1, obj2)) // true
    
    // 判断两个对象的内容不相等
    const obj1 = {
      a: 1,
      b: {
        c: 2,
        d: {
          e: 4
        }
      }
    }
    const obj2 = {
      a: 1,
      b: {
        c: 2,
        d: {
          e: 5
        }
      }
    }
    console.log(compareObject(obj1, obj2)) // false
    

    接下来再来强调一下 compareObject 函数中第 23 行这句关键代码,如果没有这条语句那么最后的返回结果只会取决于两个对象最底层属性(最后一次)的比较结果。

    if (!status) {
      break
    }
    

    例如,我将两个对象变为下面这样:

    const obj1 = {
      a: 1,
      b: {
        c: 3, // 和 obj2 不相等
        d: {
          e: 4
        }
      }
    }
    const obj2 = {
      a: 1,
      b: {
        c: 2,
        d: {
          e: 4
        }
      }
    }
    console.log(compareObject(obj1, obj2)) // true
    

    可以看到最后的返回结果是 true,因为最后的一次比较是 e 属性,它们的值是相等的。

    上面这样的写法应该还有一些情况没有考虑到,对于我的项目需求而言已经足够了,如果哪位小伙伴发现了希望可以提出来,然后再将它改进一下,非常感谢。

  • 相关阅读:
    setTimeout和setInterval的区别(面试题)
    什么是跨域?列出几种JS跨域解决方法?(前端面试题)
    建网站的流程
    CSS Sprite(雪碧图)简单使用
    前端不得不说的性能优化
    面试题
    前端如何做好SEO优化
    JavaScript string字符串对象常见方法
    微信号复制跟跳转——clipboard.js
    微信号复制跟跳转——execCommand()
  • 原文地址:https://www.cnblogs.com/zhangguicheng/p/12820148.html
Copyright © 2011-2022 走看看