美文网首页
BUG-JS对象深拷贝

BUG-JS对象深拷贝

作者: _LG_ | 来源:发表于2019-02-01 16:16 被阅读16次

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

    1.png

    场景:将一个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)是深拷贝。确并没有认真思考对象属性的值的类型,一个是不可变类型,一个是可变类型,就这样认为它们是等同的。

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

    1. 一方面知识点掌握地不够熟练
    2. 都已经定位到bug产生的地方了,但是还是理所当然地认为没有错,没有原汁原味模拟出项目中代码产生结果的每一步。

    相关文章

      网友评论

          本文标题:BUG-JS对象深拷贝

          本文链接:https://www.haomeiwen.com/subject/kanrsqtx.html