• 一文搞懂浅拷贝与深拷贝到底有什么区别


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

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

    创建对象

    首先创建一个对象。

     var obj = {
         a: 1,
         b: 2,
         c: {
             d: 3,
             e: 4,
         }
     };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

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

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

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

    拷贝

     //浅拷贝obj
     var obj1 = Object.assign({}, obj);
     //深拷贝obj
     var obj2 = JSON.parse(JSON.stringify(obj));
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改拷贝后对象参数

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

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

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

    输出查看差别

     console.log('原对象',obj);
     console.log('浅拷贝后对象',obj1);
     console.log('深拷贝后对象',obj2);
    
    
    • 1
    • 2
    • 3
    • 4

    看图——>注:我这里是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,
         }
     };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    看看输出后原对象参数——>???为什么输出的原对象的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);
    
    
    • 1
    • 2
    • 3

    结果如下:

    true

    false

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

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

  • 相关阅读:
    解决Nginx unknown directive “stream”问题
    R语言计算时间序列数据的逐次差分(successive differences):使用diff函数计算时间序列数据的逐次差分值
    reStructuredText 初学者语法汇总
    【Linux】指令详解(一)
    ubuntu20.04中安装配置docker nvidia容器来实现宿主机GPU的调用
    【html5期末大作业】基于HTML+CSS+JavaScript管理系统页面模板
    飞致云及其旗下1Panel项目进入2023年第三季度最具成长性开源初创榜单
    【面试经典150 | 区间】插入区间
    基于Python贝叶斯优化XGBoost算法调参报错“TypeError: ‘float‘ object is not subscriptable”
    FFmpeg5.1 解码rtsp 并用OpenCV 播放
  • 原文地址:https://blog.csdn.net/qq_60750453/article/details/126578104