首页>>前端>>JavaScript->JS的深浅复制,原来如此!

JS的深浅复制,原来如此!

时间:2023-11-30 本站 点击:0

摘要:之所以会出现深浅拷贝的问题,实质上是由于JS对基本类型和引用类型的处理不同。

浅复制的意思

浅复制是仅仅对数据存放在栈内的引用的复制,没有复制引用指向堆内的内容。多个数据的浅复制,这复制多个引用,这多个引用共同指向堆内的同一个内容。当一个浅复制数据做出修改,即堆内的引用指向的内容发生修改,这时,其他通过引用指向这里的数据也会随着改变。

letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=obj;objA.a='a';console.log(obj.a);//'a'console.log(objA.a);//'a'

深复制的意思

深复制是指连同堆的内容一块复制,生成一个新的对象。多个深复制将是多个不同的对象,也就有不同的引用,也就指向不同的堆内容。

使用深复制的原由

在平常开发中,有时会有数据的传递与接收,当拿到传过来的数据后,难免需要对数据进行加工和改造,为了不破坏原有数据结构,这时就可以使用深复制拷贝数据,然后处理生成的新的数据。深复制也可以防止修改多个引用后引用混乱的问题,减少BUG的产生机会。

可实现深复制的几种方法

实现方式一:JSON的序列化与反序列化

letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=JSON.parse(JSON.stringify(obj));//JSON的序列化与反序列化objA.a='a';console.log(obj.a);//1console.log(objA.a);//'a'

虽然JSON的序列化与反序列化可以实现深复制,但有几个缺点需要注意:

1、date日期对象被转成日期日期字符串

2、没法访问到原型

3、复制不了undefined的属性

4、NAN和无穷被转为NULL

letd1=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(obj);objA.a='a';console.log(obj.a);//1console.log(objA.a);//'a'

虽然Object.assign()可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=Object.assign(obj);objA.c.c1='c1';//Object.assign()仅仅是一层深复制。console.log(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'

虽然扩展运算符"…"可以实现深复制,但对于更深层次的对象引用也是仅仅浅复制。

letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA={...obj};objA.c.c1='c1';//扩展运算符"..."同Object.assign()一样,仅仅是一层深复制,不能多层深复制。console.log(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;letisObject=paramter.constructor===Object;letisArray=paramter.constructor===Array;if(isObject||isArray){target=Array.isArray(paramter)?[]:{};for(letiinparamter){tarGET@[i]=ReCopy(paramter[i]);}}else{target=paramter;}returntarget;}letobjA=ReCopy(obj);objA.c.c1='c1';console.log(obj.c.c1);//10console.log(objA.c.c1);//'c1'

ladash深拷贝

lodash深复制是更专业的深复制方式。

安装lodash

先初始化,生成package.json文件,然后使用一下命令安装。

npmi-Slodash

引入lodash

var _ = require('lodash');

使用lodash

letobj={a:1,b:2,c:{c1:10,c2:20}}
letobj={a:1,b:2,c:{c1:10,c2:20}}letobjA=JSON.parse(JSON.stringify(obj));//JSON的序列化与反序列化objA.a='a';console.log(obj.a);//1console.log(objA.a);//'a'0

本文分享自华为云社区,作者: 鑫2020。


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