BUG-JS对象深拷贝

对象深拷贝这个问题折磨了笔者好几天,简直痛不欲生。最大的问题是笔者认为自己写的都没有问题。

场景:将一个a对象拷贝给b对象,改变a对象的属性的值,b对象不发生变化。然而问题出现了,b对象属性的值也跟着a对象发生变化了。

    const a = {doctor: [{name: 'aa'}, {name: 'bb'}]};
    const b = Object.assign({}, a);

    a.doctor.push({name: 'cc'});

    console.log(a); // {doctor: [{name: 'aa'}, {name: 'bb'}, {name: 'cc'}]}
    console.log(b); // {doctor: [{name: 'aa'}, {name: 'bb'}, {name: 'cc'}]}

毫无疑问地,我认为Object.assign({}, a)是一种深拷贝方法,将a对象拷贝给b,a和b是相互独立的(之后会解释为什么这么想)。
从以上代码可以得出流程:

对象深拷贝.png

因此,需要重新构建一个数组,然后将该数组拷贝给bdoctor属性:

   const a = {doctor: [{name: 'aa'}, {name: 'bb'}]};
    const b = {};

    const c = a.doctor.map(data => {
      return data;
    });
    b['doctor'] = c;

    a.doctor.push({name: 'cc'});

    console.log(a); // {doctor: [{name: 'aa'}, {name: 'bb'}, {name: 'cc'}]}
    console.log(b); // {doctor: [{name: 'aa'}, {name: 'bb'}]}

so,这样做的话,就满足了一开始的要求。

现在来解释一波笔者为什么理所当然地认为Object.assign({}, a)是深拷贝呢?因为一开始笔者在浏览器上的console窗口,按照上面的步骤运行了一遍,如下:

测试.png

就是这样,才会如此地确定Object.assign({}, a)是深拷贝。当然Object.assign({}, a)本身就是深拷贝,它的前提是a是一级对象如:({name: ''test"},a不能是嵌套对象)。确并没有认真思考对象属性的值的类型,一个是不可变类型,一个是可变类型,就这样认为它们是等同的。

小结, 产生这个bug的原因有两点 :

  1. 一方面知识点掌握地不够熟练
  2. 都已经定位到bug产生的地方了,但是还是理所当然地认为没有错,没有原汁原味模拟出项目中代码产生结果的每一步。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,161评论 1 32
  • 属性的简洁表示法 ES6允许直接写入变量和函数,作为对象的属性和方法。 上面代码表明,ES6允许在对象之中,直接写...
    oWSQo阅读 525评论 0 0
  • 1.属性的简洁表示法 允许直接写入变量和函数 上面代码表明,ES6 允许在对象之中,直接写变量。这时,属性名为变量...
    雨飞飞雨阅读 1,170评论 0 3
  • 11月30日,写作群最后一天,突发奇想,我今天就专门不交作业!看看怎样? 想归想,说归说,时间一到,还是乖乖拿起手...
    文晓玲阅读 334评论 2 1
  • 凌晨02:29,已经到了4月5日,过去的三月很忙碌,也发生了很大变化。 加入写作打卡群已经两个月的时间,对写作确实...
    _蓝山阅读 324评论 2 2