首先明确一点,浅拷贝和深拷贝的概念,是因为栈堆内存的设计产生了,所以JavaJavaScriptPython等等,都是有这个概念的!

为了方便,我就直接拿JS来演示了。

创建对象

首先创建一个对象。

 var obj = {
     a: 1,
     b: 2,
     c: {
         d: 3,
         e: 4,
     }
 };

这个对象中,还有一个子对象,也就是obj对象中存在对象c

因为如果我们单纯一个对象,js是体现不出来这个浅拷贝与深拷贝的区别的。

如何去实现浅拷贝与深拷贝我就不说了,因为每个语言实现方法不一样,尤其JavaScript可实现方法太多,库也是一大堆,原理说清楚,啥语言都不是问题。

拷贝

 //浅拷贝obj
 var obj1 = Object.assign({}, obj);
 //深拷贝obj
 var obj2 = JSON.parse(JSON.stringify(obj));

修改拷贝后对象参数

 //修改浅拷贝对象参数的值
 obj1.c.d = 5;
 //修改深拷贝对象参数的值
 obj2.c.e = 6;

注:obj1obj2都是拷贝了obj对象的内容。

此时可能还没有什么差别体现,我们输出一下就明白了。

输出查看差别

 console.log('原对象',obj);
 console.log('浅拷贝后对象',obj1);
 console.log('深拷贝后对象',obj2);

看图——>注:我这里是ts写,运行也是用ts-node直接运行,其他语言用其他语言方法。

结果如下:

原对象 { a: 1, b: 2, c: { d: 5, e: 4 } }
浅拷贝后对象 { a: 1, b: 2, c: { d: 5, e: 4 } }
深拷贝后对象 { a: 1, b: 2, c: { d: 3, e: 6 } }

 //注意看原来定义对象参数
 var obj = {
     a: 1,
     b: 2,
     c: {
         d: 3,
         e: 4,
     }
 };

看看输出后原对象参数——>???为什么输出的原对象的d的值变成了5

再想想,我们是不是给浅拷贝的d重新赋值了个5

思考——>为什么这个5不仅仅是赋值到了obj1,也就是浅拷贝后对象上,赋值到了原对象obj上。

原因是,obj1c这个对象其实不是复制一份obj中的c,而是引用!!!

也就是obj1obj中的c都是指向了——>obj对象创建时在栈堆内存c对象。

我画个图,凑合看看吧:

objobj1中的c对象,最终都是指向同一个内存地址。

那既然指向是同一个,那自然改了obj1中的cobjc也改了。

注意!那深拷贝相反,深拷贝它是直接复制的。

它里面的c也是直接新开辟了一个内存,而不是obj原来的c的那块内存,所以obj的c != obj2的c

那你可能会问,怎么样证明是不是同一个呢?

简单!输出一下不就知道了:

 console.log(obj.c === obj1.c);
 console.log(obj.c === obj2.c);

结果如下:

true

false

可以看出,obj1c指向的内存与objc相同,而obj2c指向的内存与obj的不同。

所以,深拷贝中的c对象值改变不会影响到原来对象。浅拷贝会影响

最后修改:2022 年 08 月 24 日
如果觉得我的文章对你有用,请随意赞赏