当前位置: 首页 > Web前端 > HTML

JavaScript深拷贝、浅拷贝详解

时间:2023-03-28 16:35:17 HTML

在开发过程中,有时会遇到需要将一个已有对象的所有成员属性拷贝到另一个对象中,这就是拷贝。接下来,让我们谈谈JavaScript中的复制。在JavaScript中,我们的拷贝分为两类,一类是深拷贝,一类是浅拷贝。那么如何区分深拷贝和浅拷贝呢?浅拷贝就是直接将一个Object对象的所有属性和属性值复制到另一个Object对象中。这样做的结果是新对象和旧对象的Object类型的属性值相同,指向同一块内存,即新对象和旧对象的Object类型的属性值相同,指向同一块内存。因此,修改新对象或修改原有对象都会相互干扰。深拷贝就是将一个Object对象的内容完全复制到一个新的对象中。修改原对象的属性或属性值不会影响新对象。原对象和新对象完全独立,互不影响。它们究竟是如何应用的?让我们举几个例子来说明。1、浅拷贝比如我们现在有一个对象A,它有两个属性id和name,还有一个空的对象B,那么我们应该如何将A对象的属性拷贝到B对象中呢?varA={name:'xl',id:6};varB={};首先,我们可以通过一个for...in循环遍历对象A,然后将得到的每一项赋值给对象B。然后通过打印对象B来检查A的属性值是否复制成功。for(kinA){//k为属性名,A[k]为属性值B[k]=A[k];}console.log(B);打印结果为:发现B确实复制了A的所有属性。根据上面的例子,我们现在正在为A对象添加一个方法,我们来看看复制的结果吧!复制代码varA={name:'xl',id:6,study:{doing:'learning'}};打印出来的结果是:看来我们新添加的方法复制成功了,但是如果我们修改B对象,A对象中的值会不会改变为学习的值呢?复制代码B.study.doing='Class';控制台日志(A);打印结果为:可以看出A中的属性也进行了相应的更改。这是因为我们浅拷贝的方法是深层对象的地址。解释:浅拷贝只复制一层,只复制更深的对象层的引用。我们也可以通过ES6的新语法Object.assign(target,...sources)来实现我们的浅拷贝。我们通过这个方法来看看上面的例子。varA={name:'xl',id:6,study:{doing:'study'}};varB={};Object.assign(B,A);console.log(B);打印结果为:可见我们的语法也可以达到效果,但是需要注意的是这种方法只能实现浅拷贝。复制代码2.深复制对于深复制,我们的实现思路是:然后通过循环表复制对象中的属性和属性名。这里用到了递归的思想。还是上面的例子:首先我们封装一个函数,传入要复制的对象和要复制的对象。封装完成后,我们遍历for..in循环。接下来的具体操作是:1.通过oldA[k]获取属性值2.通过instanceof()判断值的属性3.如果值的类型是数组或者对象,则循环遍历数组或者对象通过递归调用复制值。4.如果值的类型是简单数据类型,直接赋值。代码如下:,item)}elseif(iteminstanceofObject){newA[k]={};deepCopy(newA[k],item)}else{newA[k]=item;}}}deepCopy(B,A);控制台日志(B);最终打印出来的结果是:复制成功。那么如果我们改变B对象的study方法中的值,会不会影响到A呢?复制代码B.study.doing='class';控制台日志(A);打印结果为:可以发现,B对象中值的变化不会影响A对象。因为:深拷贝就是将一个Object对象的内容完全复制到一个新的对象中。复制代码相信大家通过前端培训到现在应该已经了解了深拷贝和浅拷贝。那么,它们之间有什么区别呢?浅拷贝和深拷贝的区别浅拷贝就是拷贝对象的引用。当原始对象发生变化时,复制的对象也会发生变化;深拷贝是再申请一块内存,内容和原对象一样,改变原对象,拷贝对象不变。