摘要:深浅拷贝问题的产生本质上是JS对基本类型和引用类型的处理方式不同。本文分享自华为云社区《js的深浅复制,一看就明白》,作者:Xin2020。浅拷贝是指浅拷贝只是拷贝栈中存储的数据的引用,不拷贝引用指向堆中的内容。多个数据的浅拷贝,即复制多个引用,这些引用共同指向堆中的相同内容。当一个浅拷贝数据被修改,即堆中引用指向的内容被修改时,此时引用指向这里的其他数据也会随之改变。让obj={a:1,b:2,c:{c1:10,c2:20}}让objA=obj;objA.a='a';console.log(obj.a);//'a'console.log(objA.a);//'a'deepcopy意思是深拷贝是指连同堆中的内容一起拷贝,生成一个新的对象。多个深拷贝会是多个不同的对象,它们会有不同的引用,会指向不同的堆内容。使用深拷贝的原因在平时的开发中,有时候会有数据的收发。得到传输的数据后,不可避免地要对数据进行处理和转换。为了不破坏原有的数据结构,此时可以使用。深拷贝复制数据,然后处理生成的新数据。深拷贝也可以防止修改多个引用后出现引用混淆的问题,减少BUG出现的几率。有几种方法可以实现深拷贝。实现方法一:JSON的序列化和反序列化letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=JSON.parse(JSON.stringify(obj));//JSON的序列化与反序列化objA.a='a';控制台日志(obj.a);//1console.log(objA.a);//'a'虽然JSON的序列化和反序列化可以实现深拷贝,但是有几个缺点需要注意:1.date日期对象转换成日期字符串2.无法访问原型3.未定义的属性不可复制4.NAN和infinity转为NULLletd1=newDate();letobj={d1,d2:undefined,d3:NaN}letobjD=JSON.parse(JSON.stringify(obj));console.log(obj)console.log(objD)实现方式二:Object.assign()letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=Object.assign(对象);objA.a='a';控制台日志(obj.a);//1console.log(objA.a);//'a'虽然Object.assign()可以实现深拷贝,但是对于更深的对象References也只是浅拷贝。让obj={a:1,b:2,c:{c1:10,c2:20}}让objA=Object.assign(obj);objA.c.c1='c1';//Object.assign()只是一层深拷贝。控制台日志(obj.c.c1);//'c1'console.log(objA.c.c1);//'c1'实现方式三:扩展运算符letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA={...obj};;objA.a='a';console.log(obj.a);//1console.log(objA.a);//'a',虽然展开运算符“...”可以实现深拷贝,但是对于更深层次的对象引用,它只是浅拷贝。让obj={a:1,b:2,c:{c1:10,c2:20}}让objA={...obj};objA.c.c1='c1';//spreadoperator"..."和Object.assign()一样,只是一层深拷贝,不是多层深拷贝。控制台日志(obj.c.c1);//'c1'console.log(objA.c.c1);//'c1'实现方式四:使用递归实现深拷贝,实现多层深拷贝则可以使用递归循环拷贝。letobj={a:1,b:2,c:{c1:10,c2:20}}constReCopy=function(paramter){lettarget=null;让isObject=paramter.constructor===对象;让isArray=paramter.constructor===数组;如果(isObject||isArray){target=Array.isArray(参数)?[]:{};for(letiinparamter){target[i]=ReCopy(paramter[i]);}}else{目标=参数;}返回目标;}letobjA=ReCopy(obj);objA.c.c1='c1';console.log(obj.c.c1);//10console.log(objA.c.c1);//'c1'ladashdeepcopylodashdeepcopy是一种比较专业的深拷贝方式。安装lodash首先要进行初始化,生成一个package.json文件,然后使用下面的命令进行安装。npmi-Slodashimportlodashvar_=require('lodash');使用lodash让obj={a:1,b:2,c:{c1:10,c2:20}}让objA=_.cloneDeep(obj);objA.c.c1='c1';控制台日志(obj.c.c1);//10console.log(objA.c.c1);//'c1'点击关注,第一时间了解华为云新鲜技术~
