深比较的方法有哪些?

简介: 【10月更文挑战第29天】

递归比较

  • 原理:通过递归遍历对象或数组的所有属性和元素,对每个属性或元素进行逐一比较,直到比较完所有层级的内容。
  • 示例
function deepEqual(obj1, obj2) {
   
  if (obj1 === obj2) {
   
    return true;
  }

  if (typeof obj1!== 'object' || obj1 === null || typeof obj2!== 'object' || obj2 === null) {
   
    return false;
  }

  if (Array.isArray(obj1) && Array.isArray(obj2)) {
   
    if (obj1.length!== obj2.length) {
   
      return false;
    }
    for (let i = 0; i < obj1.length; i++) {
   
      if (!deepEqual(obj1[i], obj2[i])) {
   
        return false;
      }
    }
    return true;
  } else {
   
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length!== keys2.length) {
   
      return false;
    }

    for (let key of keys1) {
   
      if (!obj2.hasOwnProperty(key) ||!deepEqual(obj1[key], obj2[key])) {
   
        return false;
      }
    }

    return true;
  }
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(deepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(deepEqual(obj3, obj4)); // true

JSON序列化比较

  • 原理:先将对象或数组转换为JSON字符串,然后比较这两个JSON字符串是否相等。如果相等,则说明两个对象或数组的内容在结构和值上是相同的。
  • 示例
function jsonDeepEqual(obj1, obj2) {
   
  return JSON.stringify(obj1) === JSON.stringify(obj2);
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(jsonDeepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(jsonDeepEqual(obj3, obj4)); // true

不过需要注意的是,JSON序列化比较要求对象的属性值必须是能够被JSON序列化的数据类型,如函数、正则表达式等特殊类型在序列化时会丢失信息,导致比较结果不准确。

lodash库的_.isEqual方法

  • 原理:lodash是一个常用的JavaScript工具库,其中的 _.isEqual 方法实现了深度比较的功能。它能够递归地比较对象、数组以及各种数据类型的差异,并且能够处理循环引用等复杂情况。
  • 示例
    首先需要安装lodash库,然后可以这样使用:
const _ = require('lodash');

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(_.isEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(_.isEqual(obj3, obj4)); // true

自定义深度比较函数

  • 原理:根据具体的业务需求和对象结构,编写自定义的深度比较函数,在函数中明确指定比较的规则和逻辑,对对象的各个属性和嵌套层次进行细致的比较。
  • 示例
function customDeepEqual(obj1, obj2) {
   
  // 比较对象的类型是否相同
  if (Object.prototype.toString.call(obj1)!== Object.prototype.toString.call(obj2)) {
   
    return false;
  }

  if (typeof obj1 === 'object' && obj1!== null) {
   
    const keys1 = Object.keys(obj1);
    const keys2 = Object.keys(obj2);

    if (keys1.length!== keys2.length) {
   
      return false;
    }

    for (let key of keys1) {
   
      if (!obj2.hasOwnProperty(key)) {
   
        return false;
      }

      if (typeof obj1[key] === 'object' && obj1[key]!== null) {
   
        if (!customDeepEqual(obj1[key], obj2[key])) {
   
          return false;
        }
      } else {
   
        if (obj1[key]!== obj2[key]) {
   
          return false;
        }
      }
    }
  }

  return true;
}

let obj1 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };
let obj2 = {
    name: 'Alice', age: 25, hobbies: ['reading', 'swimming'] };

console.log(customDeepEqual(obj1, obj2)); // true

let obj3 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };
let obj4 = {
    name: 'Alice', age: 25, details: {
    city: 'New York' } };

console.log(customDeepEqual(obj3, obj4)); // true

这些深比较的方法各有优缺点,在实际应用中,可以根据具体的场景和需求选择合适的方法来进行深度比较。递归比较方法较为灵活但需要自己处理各种边界情况;JSON序列化比较简单直接但对数据类型有一定限制;使用lodash库的 _.isEqual 方法方便快捷且功能强大,但需要引入额外的库;自定义深度比较函数则可以根据特定的业务逻辑进行精确的比较。

相关文章
|
算法 数据安全/隐私保护 Python
哈希算法(hash)加密解密
哈希算法(hash)加密解密
11658 11
哈希算法(hash)加密解密
|
存储 SQL 数据库
数据库设计案例:电商系统数据库设计实践
数据库设计案例:电商系统数据库设计实践
2428 1
|
自然语言处理 前端开发 开发工具
webpack 热更新
【10月更文挑战第23天】Webpack 热更新是一项非常实用的技术,它为前端开发带来了极大的便利和效率提升。通过深入了解其原理和应用,开发者可以更好地利用热更新功能,提高开发质量和速度。
|
Shell Linux
在Linux中,什么是环境变量?如何设置和查看环境变量?
在Linux中,什么是环境变量?如何设置和查看环境变量?
|
11月前
|
安全 算法
搬运5款让你电脑更好用的小软件
本文介绍了五款实用的电脑软件,包括文件夹移动工具FolderMove、文件整理工具DropIt、微信空号检测软件燃精灵、图片放大软件BenVista PhotoZoom以及任务管理工具Todoist。这些软件能帮助你提升电脑使用效率、美化界面、保障安全,快来试试吧!
169 3
|
JavaScript 算法
【Vue面试题六】、为什么Vue中的 v-if 和 v-for 不建议一起用?
这篇文章解释了Vue中`v-if`和`v-for`不建议一起使用的原因,因为`v-for`具有更高的优先级,同时使用会导致性能浪费。文章建议使用`<template>`标签来包裹`v-if`和`v-for`,以优化性能,并通过计算属性提前过滤不需要显示的项。
【Vue面试题六】、为什么Vue中的 v-if 和 v-for 不建议一起用?
|
存储 前端开发 安全
【面试题】: bs架构与cs架构的区别以及各自优缺点
bs架构与cs架构的区别以及各自优缺点
5806 0
|
缓存 负载均衡 Java
Spring Boot 优雅实现多活架构(Active-Active Architecture)
【6月更文挑战第20天】实现多活架构(Active-Active Architecture)意味着在多个地理位置或多个数据中心同时运行应用系统,使其具备高可用性、灾难恢复和负载均衡能力。以下从理论到实践详细介绍如何使用 Spring Boot 构建多活系统。
321 6