首先明确一点,浅拷贝和深拷贝的概念,是因为栈堆内存的设计产生了,所以
Java、JavaScript、Python等等,都是有这个概念的!
为了方便,我就直接拿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;
注:obj1和obj2都是拷贝了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上。原因是,
obj1中c这个对象其实不是复制一份obj中的c,而是引用!!!也就是
obj1和obj中的c都是指向了——>obj对象创建时在栈堆内存中c对象。
我画个图,凑合看看吧:

obj和obj1中的c对象,最终都是指向同一个内存地址。
那既然指向是同一个,那自然改了obj1中的c,obj的c也改了。
注意!那深拷贝就相反,深拷贝它是直接复制的。
它里面的c也是直接新开辟了一个内存,而不是obj原来的c的那块内存,所以obj的c != obj2的c。
那你可能会问,怎么样证明是不是同一个呢?
简单!输出一下不就知道了:
console.log(obj.c === obj1.c);
console.log(obj.c === obj2.c);
结果如下:

true
false
可以看出,obj1的c指向的内存与obj的c相同,而obj2的c指向的内存与obj的不同。
所以,深拷贝中的c对象值改变不会影响到原来对象。浅拷贝会影响。