前端之深拷贝

news2024/9/24 1:23:35

前提:

就是在实际开发中,我有一个编辑的弹窗,可以查看和编辑,因为弹窗里面是一个步骤条,点击下一步就要向对应的接口发送请求,考虑到就比如我点击下一步,此次表箱信息其实不需要修改,我要修改的是控制器的信息,那么点击下一步发送请求其实是没有必要的,我就考虑到了进行比对,如果没有变化就直接下一步,不发送请求

我的想法是,在点击编辑时,把变化前的值给一个变量(旧值),然后在点击下一步用现在的值和旧值进行对比

const editDataBox = ref<any>({});
const initialFormData = ref<any>({});
//编辑
const handleEdit = async (data: any) => {
  editVisible.value = true;
//在弹窗弹出的时候,把传递过来的值给一个变量
  initialFormData.value=data
editDataBox.value = data;
....
}
const isFormDataEqual = (formData1: any, formData2: any) => {
  return JSON.stringify(formData1) === JSON.stringify(formData2);
};
//下一步
const editNext = () => {
 switch (editCurrent.value) {
 case 1:
 const formDataChanged = !isFormDataEqual(editDataBox.value, initialFormData.value);
  if (formDataChanged) {
...
}else{
  editCurrent.value += 1;
}
}

这是我刚开始的想法,原本我以为就是initialFormData这个值不会变化,然后我发现表单值变化了也没有发送请求,我就输出formDataChanged这个值,发现每次都是false,进而输出initialFormData它的值,就发现它既然是变化后的值,我就想问题在哪里,原因是:

在 JavaScript 中,当你将一个对象赋值给另一个变量时,实际上是将对象的引用赋值给了这个变量,而不是对象本身的拷贝。这意味着,如果你修改了其中一个变量所引用的对象,另一个变量也会受到影响,因为它们引用的是同一个对象。

在你的代码中,initialFormDataeditDataBox 都是使用 ref 创建的响应式对象。当你在 handleEdit 函数中将 data 赋值给 initialFormData.valueeditDataBox.value 时,它们实际上是引用了同一个对象。

因此,当你修改 editDataBox.value 后,initialFormData.value 也会受到影响,因为它们引用的是同一个对象。

为了避免这种情况,你需要确保 initialFormDataeditDataBox 引用的是不同的对象,而不是同一个对象的引用。这就是为什么需要进行深拷贝的原因,因为深拷贝会创建一个新的对象,其值与原始对象相同,但是引用不同,这样就可以独立地修改新对象而不影响原始对象。

我的解决办法是使用 JSON.parse() 和 JSON.stringify() 进行深拷贝,修改后的代码是,加了一个deepCopy函数进行深拷贝

JSON.parse() 和 JSON.stringify()

const editDataBox = ref<any>({});
const initialFormData = ref<any>({});
const deepCopy = (obj: any) => {
  return JSON.parse(JSON.stringify(obj));
};
//编辑
const handleEdit = async (data: any) => {
  editVisible.value = true;

 initialFormData.value = deepCopy(data);
editDataBox.value = data;
....
}
const isFormDataEqual = (formData1: any, formData2: any) => {
  return JSON.stringify(formData1) === JSON.stringify(formData2);
};
//下一步
const editNext = () => {
 switch (editCurrent.value) {
 case 1:
 const formDataChanged = !isFormDataEqual(editDataBox.value, initialFormData.value);
  if (formDataChanged) {
...
}else{
  editCurrent.value += 1;
}
}

使用 Object.assign():

这个方法只能实现浅拷贝,但如果对象的结构比较简单且不包含嵌套对象,也可以考虑使用它 

const deepCopy = (obj) => {
  return Object.assign({}, obj);
};

 使用递归:

可以编写一个递归函数来遍历对象的所有属性,并对每个属性进行拷贝。这需要一些额外的代码,但也是一个有效的方法。

const deepCopy = (obj) => {
  if (typeof obj !== 'object' || obj === null) {
    return obj;
  }

  let newObj = Array.isArray(obj) ? [] : {};

  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      newObj[key] = deepCopy(obj[key]);
    }
  }

  return newObj;
};

使用 Lodash 库 

Lodash 提供了 _.cloneDeep() 方法,可以实现对象的深拷贝。这是一个非常流行且易于使用的方法。

const _ = require('lodash');

// 使用 _.cloneDeep() 进行深拷贝
const deepCopy = (obj) => {
  return _.cloneDeep(obj);
};

深拷贝在编程中几个重要的优势和应用场景: 

  1. 数据独立性: 深拷贝创建了原始对象的完全独立副本,这意味着修改拷贝后的对象不会影响原始对象。这对于需要在多个地方使用同一份数据,但又需要独立修改数据的情况非常有用。

  2. 避免引用问题: 在 JavaScript 中,如果你简单地将一个对象赋值给另一个变量,实际上是将对象的引用传递给了新变量。这意味着如果你修改了新变量中的对象,原始对象也会受到影响。深拷贝可以避免这种问题,因为它创建了一个完全独立的对象,不会共享内存地址。

  3. 数据传递: 在许多情况下,你可能需要将数据传递给其他函数或组件,并且希望确保传递的是数据的副本而不是引用。深拷贝可以确保你传递的是数据的完整副本,而不会影响原始数据。

  4. 数据比较: 当需要比较两个对象是否相等时,深拷贝可以确保比较的是对象的值而不是引用。这在进行单元测试、数据验证或其他需要比较对象的场景中非常有用。

总的来说,深拷贝是一种保护数据完整性和独立性的重要工具,可以帮助避免由于对象共享引起的意外行为,并确保数据在不同部分之间的传递和修改时保持一致。

你学会了吗?

嗯,可能有的朋友还不太了解JSON.parse() 和 JSON.stringify()?我也是一知半解。

我在想应该写在另一篇文章还是写在这里?emmm,还是重新写一个吧,可以点击跳转

最后,我也是刚入行时间不长的前端,如果有写的有什么问题欢迎指正与交流。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1645114.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux —— 信号(2)

Linux —— 信号&#xff08;2&#xff09; 信号的序号kill系统调用不可被自定义的信号raiseabort 异常传递信号SIGFPESIGSEGV alarm传递信号 我们今天来接着了解信号&#xff1a; 信号的序号 我们来看看信号的序号&#xff1a; 信号的序号是从1开始&#xff0c;到31我们称这…

为什么要梯度累积

文章目录 梯度累积什么是梯度累积如何理解理解梯度累积梯度累积的工作原理 梯度累积的数学原理梯度累积过程如何实现梯度累积 梯度累积的可视化 梯度累积 什么是梯度累积 随着深度学习模型变得越来越复杂&#xff0c;模型的训练通常需要更多的计算资源&#xff0c;特别是在训…

【热门话题】ElementUI 快速入门指南

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 ElementUI 快速入门指南环境准备安装 ElementUI创建 Vue 项目安装 ElementUI 基…

Android selinux权限

一.SE 概述 SELinux 是由美国NSA&#xff08;国安局&#xff09;和 SCC 开发的 Linux的一个扩张强制访问控制安全模块。原先是在Fluke上开发的&#xff0c;2000年以 GNU GPL 发布。从 fedora core 2开始&#xff0c; 2.6内核的版本都支持SELinux。 在 SELinux 出现之前&#…

开源模型应用落地-CodeQwen模型小试-小试牛刀(一)

一、前言 代码专家模型是基于人工智能的先进技术&#xff0c;它能够自动分析和理解大量的代码库&#xff0c;并从中学习常见的编码模式和最佳实践。这种模型可以提供准确而高效的代码建议&#xff0c;帮助开发人员在编写代码时避免常见的错误和陷阱。 通过学习代码专家模型&…

百度语音识别开发笔记

目录 简述 开发环境 1、按照官方文档步骤开通短语音识别-普通话 2、创建应用 3、下载SDK 4、SDK集成 5、相关接口简单说明 5.1权限和key 5.2初始化 5.3注册回调消息 5.4开始转换 5.5停止转换 6、问题 简述 最近想做一些语音识别的应用&#xff0c;对比了几个大厂…

电路笔记 :芯片封装、电阻电容封装类型介绍

芯片的零件型号、位号和封装 项目定义作用零件型号每个零件在设计和制造中的唯一标识符号用于识别零件的特定规格、制造商和其他重要信息位号在电路图或设计图纸上标识每个零件位置的符号帮助准确定位每个零件的位置&#xff0c;以便正确安装到相应位置上封装电子元器件的外部…

AXS2005 2.4W单通道AB类音频功率放大器 兼容HAA8002,LTK8002,NS8002

深圳市润泽芯电子有限公司为爱协生一级代理 技术支持 欢迎试样~Tel&#xff1a;18028786817 AXS2005是爱协生推出的2.4W单通道AB类音频功率放大器 可兼容HAA8002&#xff0c;LTK8002&#xff0c;NS8002&#xff0c;XS8002&#xff0c;XA8002&#xff0c;8002B。 简介 AXS2005…

网络基础(1)网络编程套接字TCP,守护进程化

TCP协议 下面我们来学习一下TCP套接字的使用。 也就是使用一下基本的接口。首先TCP套接字的使用和UDP套接字的使用是大同小异的&#xff0c;但是多了一些步骤。 这里回顾一下&#xff1a;UDP是不可靠的&#xff0c;无连接的协议。而TCP则是可靠的&#xff0c;面向连接的协议…

LNMP部署wordpress

1.环境准备 总体架构介绍 序号类型名称外网地址内网地址软件02负载均衡服务器lb0110.0.0.5192.168.88.5nginx keepalived03负载均衡服务器lb0210.0.0.6192.168.88.6nginx keepalived04web服务器web0110.0.0.7192.168.88.7nginx05web服务器web0210.0.0.8192.168.88.8nginx06we…

真希望我父母读过这本书的笔记(二)

系列文章目录 真希望我父母读过这本书的笔记&#xff08;一&#xff09; 真希望我父母读过这本书的笔记&#xff08;二&#xff09; 文章目录 系列文章目录PART 5 培养心理健康的孩子亲子关系决定心理健康互动及来回交流如何开始交流互看游戏交流恐惧症 若遇棘手之际&#xff0…

机器学习---朴素贝叶斯

朴素贝叶斯是一种用于分类和预测任务的算法&#xff0c;他的原理是基于贝叶斯定理。其中朴素的意思是假设各特征之间相互独立。这个实验我是用的老师课后作业的题目预测某天是否会打乒乓球&#xff0c;假设每个特征独立。 目录 贝叶斯公式&#xff1a; 训练集&#xff1a; 处…

视频剪辑:视频文件元数据修改工具,批量操作提升效率和准确性

在视频剪辑和后期处理的过程中&#xff0c;除了对视频本身的编辑和修改&#xff0c;元数据的管理和修改同样重要。元数据&#xff0c;如标题、艺术家、专辑封面等&#xff0c;不仅提供了视频文件的基本信息&#xff0c;还有助于更好地组织、搜索和共享视频内容。而针对视频文件…

微信答题链接怎么做_新手也能快速上手制作

在数字营销日新月异的今天&#xff0c;如何有效吸引用户参与、提升品牌曝光度&#xff0c;成为了每一个营销人都在思考的问题。而微信答题链接&#xff0c;作为一种新兴的互动营销方式&#xff0c;正以其独特的魅力&#xff0c;在营销界掀起一股新的热潮。今天&#xff0c;就让…

XSS Challenges 靶场通关解析

前言 XSS Challenges&#xff08;跨站脚本攻击挑战&#xff09;是一种用于学习和测试跨站脚本&#xff08;XSS&#xff09;漏洞的实验性平台。这些挑战旨在帮助安全研究人员和开发人员了解XSS漏洞的工作原理、检测方法和防御技巧。 通常&#xff0c;XSS Challenges平台提供一…

高德地图在vue3项目中使用:实现画矢量图、编辑矢量图

使用高德地图实现画多边形、矩形、圆&#xff0c;并进行编辑保存和回显。 1、准备工作 参考高德地图官网&#xff0c;进行项目key申请&#xff0c;链接: 准备 2、项目安装依赖 npm i amap/amap-jsapi-loader --save3、地图容器 html <template><!-- 绘制地图区域…

使用脚本启动AppImage应用程序

因为特殊需求不能直接双击运行appimage程序&#xff0c;需要用到脚本启动 1.创建一个.desktop文件 2.添加以下内容 [Desktop Entry] //这是一个配置的开始 TypeApplication //定义了应用程序的类型&#xff0c;这里是Application Namemyapp //应用程序的名称 //应用…

ASP.NET网络商店销售管理系统的设计与实现

摘 要 随着软件技术的不断进步和发展&#xff0c;信息化的管理方式越来越广泛的应用于各个领域&#xff0c;对于任何网站系统的管理来说开发一套现代化的成员管理软件是十分必要的。通过这样的软件系统&#xff0c;可以做到成员的规范管理和快速查询&#xff0c;从而减少管理…

小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具

文章目录 小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具概述笔记效果编译AStyle的DLL初次使用接口的小疑惑测试程序 - 头文件测试程序 - 实现文件测试程序 - RC备注END 小工具 - 用Astyle的DLL封装一个对目录进行代码格式化的工具 概述 上一个实验(vs2019 - ast…

记对MYSQL蜜罐的溯源反制研究

Mysql蜜罐的利用 Mysql任意文件读取 mysql蜜罐通过搭建一个简单的mysql服务&#xff0c;如果攻击者对目标客户进行3306端口爆破&#xff0c;并且用navicat等工具连接蜜罐服务器&#xff0c;就可能被防守方读取本地文件&#xff0c;包括微信配置文件和谷歌历史记录等等&#x…