当前位置: 首页 > news >正文

父子组件的传参问题,一方改变,另一方随之改变

目录

1.问题

2.解决方案

3.前端中的深拷贝及浅拷贝问题总结


1.问题

在子组件中通过emit调用父组件的方法,并传递参数,当子组件中修改传递给父组件的参数时,即使没有将修改后的值传递给父组件,父组件中的值依然修改了。

原因是传递的参数是一个对象,是引用类型,父组件中定义的变量存储的是引用类型的地址,双方指向同一个内存地址,所以只要有一方改变,另一方也会随之改变。

2.解决方案

①JSON.parse(JSON.stringify(obj))

使用JSON进行处理,但是这种简单粗暴的方法有其局限性。当值为 undefined、function、symbol 会在转换过程中被忽略。所以,对象值有这三种的话用这种方法会导致属性丢失。

②进行深拷贝处理

3.前端中的深拷贝及浅拷贝问题总结

①简单对象的深拷贝及浅拷贝

  // 简单对象的浅拷贝let obj1 = {id: '1', name: '小孙', age: 18}let obj2 = obj1console.log(obj1 === obj2) // true 代表两个对象是同一个实例,对应内存中同一个内存地址,一方修改另一方随之改变obj1.id = '2'console.log(obj2) //Object { id: "2", name: "小孙", age: 18 }obj2.name="小林"console.log(obj1) //Object { id: "2", name: "小林", age: 18 }// 简单对象的深拷贝let obj3 = {...obj1}console.log(obj1 === obj3) // falselet obj4 = Object.assign({}, obj1)console.log(obj1 === obj4) // false

深拷贝中可以使用扩展运算符,生成新的对象,也可以使用Object的assign方法

扩展运算符说明:是三个点(...),它可以用于展开,复制,合并数组或者对象。如果有重复的内容,后面的覆盖前面的。当使用扩展运算符展开一个对象时,会创建一个新的对象,两个对象之间是独立的没有任何关联。

展开
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5, 6];
console.log(arr2); // 输出:[1, 2, 3, 4, 5, 6]合并
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const combinedArr = [...arr1, ...arr2];
console.log(combinedArr); // 输出:[1, 2, 3, 4, 5, 6]复制
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2); // 输出:[1, 2, 3]

②简单数组的深拷贝和浅拷贝

  // 简单数组的浅拷贝let arr1 = ['1', '2', '3', '4']let arr2 = arr1console.log(arr1 === arr2)  // true 代表两个对象是同一个实例,对应内存中同一个内存地址// 简单数组的深拷贝let arr3 = arr1.concat()console.log(arr1 === arr3) // falselet arr4 = arr1.slice(0)console.log(arr1 === arr4) // falselet arr5 = Object.assign([], arr1)console.log(arr1 === arr5) // falselet arr6 = [...arr1]console.log(arr1 == arr6) // false

③复杂对象的深拷贝及浅拷贝

  // 复杂对象中的外层对象的深拷贝,内层对象或数组的浅拷贝let obj10 = {info:{id:'1',name:'小李',age:25},ke:['1','2','3','4']}let obj11 = {...obj10}console.log(obj10 === obj11) // falseconsole.log(obj10.info === obj11.info)  // trueconsole.log(obj10.ke === obj11.ke) // true// 如只做了外层对象或者数组的深拷贝,但是内部的对象和数组是浅拷贝,一方发生改变,另一方随之改变// 复杂对象中的外层对象的深拷贝,内层对象或数组的深拷贝let obj12 = {}Object.entries(obj10).forEach(([key,val]) =>{if(Object.prototype.toString.call(val) == '[object Object]'){obj12[key] = {...val}}else if(Object.prototype.toString.call(val) == '[object Array]'){obj12[key] = val.concat()}})console.log(obj12)console.log(obj12 === obj10) //falseconsole.log(obj10.info === obj12.info)  // falseconsole.log(obj10.ke === obj12.ke) // false

需要注意的是,如果对象内嵌套数组或者对象,如果只使用扩展运算符,只是对外层的对象做了深拷贝处理,但是对象内的数组或者对象,依然是浅拷贝,所以需要循环进行处理。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JQuery+HTML+JavaScript:实现地图位置选取和地址模糊查询
  • 图片上传成功却无法显示:静态资源路径配置问题解析
  • GUL图形化界面操作(上部)
  • 大厂面试官问我:两个1亿行的文件怎么求交集?【后端八股文十五:场景题合集】
  • 基于jeecgboot-vue3的Flowable流程-自定义业务表单流程历史信息显示
  • nginx漏洞修复 ngx_http_mp4_module漏洞(CVE-2022-41742)【低可信】 nginx版本升级
  • C++之栈和队列使用及模拟实现
  • 【讲解下iCloud如何高效利用】
  • React前端面试每日一试 3.状态(State)和属性(Props)的区别是什么?
  • Golang | Leetcode Golang题解之第264题丑数II
  • html+css 边框滑动按钮效果
  • [用AI日进斗金系列③]用CodeFlying在企微接单自动生成一个固定资产管理系统
  • Delphi5实现鱼C屏幕保护程序
  • 35_YOLOX网络详解
  • Python游戏开发之制作捕鱼达人游戏-附源码
  • JS 中的深拷贝与浅拷贝
  • 【css3】浏览器内核及其兼容性
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • Computed property XXX was assigned to but it has no setter
  • github从入门到放弃(1)
  • hadoop集群管理系统搭建规划说明
  • Iterator 和 for...of 循环
  • laravel with 查询列表限制条数
  • Tornado学习笔记(1)
  • 安装python包到指定虚拟环境
  • 每个JavaScript开发人员应阅读的书【1】 - JavaScript: The Good Parts
  • 前端相关框架总和
  • 三分钟教你同步 Visual Studio Code 设置
  • 移动端解决方案学习记录
  • 译有关态射的一切
  • 智能合约开发环境搭建及Hello World合约
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • 进程与线程(三)——进程/线程间通信
  • ​Benvista PhotoZoom Pro 9.0.4新功能介绍
  • ​Linux·i2c驱动架构​
  • ​什么是bug?bug的源头在哪里?
  • #、%和$符号在OGNL表达式中经常出现
  • #android不同版本废弃api,新api。
  • #define
  • #每天一道面试题# 什么是MySQL的回表查询
  • $(selector).each()和$.each()的区别
  • $.ajax()
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (3) cmake编译多个cpp文件
  • (32位汇编 五)mov/add/sub/and/or/xor/not
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (八)Flask之app.route装饰器函数的参数
  • (附程序)AD采集中的10种经典软件滤波程序优缺点分析
  • (附源码)ssm考试题库管理系统 毕业设计 069043
  • (汇总)os模块以及shutil模块对文件的操作
  • (亲测)设​置​m​y​e​c​l​i​p​s​e​打​开​默​认​工​作​空​间...
  • (三) prometheus + grafana + alertmanager 配置Redis监控
  • (学习日记)2024.01.09
  • (原+转)Ubuntu16.04软件中心闪退及wifi消失