浅拷贝与深拷贝

104 阅读2分钟

首先,在提及浅拷贝与深拷贝的区别时。我们应该知道深拷贝与浅拷贝是针对对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这个时候你修改两者中的任何一个的值都不会影响另一个,而对于对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变。


浅拷贝:浅拷贝只是拷贝一层,更深层次的对象级别的只拷贝引用

下面我创建了两个对象,其中一个空对象作为我浅拷贝的对象,我们通过遍历对象的方法将obj中的属性与值拷贝到了对象o中,但是随着我们对obj中数据的更改,我们发现o中的值也同样发生了改变,由此可以看出浅拷贝只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变

let obj = {
            name: 'xiaomin',
            id: 1,
            msg: {
                age: 18,
            },
        };
        let o = {};
        
         for (let k in obj) {
            //k是属性名 ,obj[k] 是属性值
            o[k] = obj[k];
        }

        obj.msg.age = 20;
        console.log(o);
        console.log(obj);

image.png

浅拷贝在es6中的新方法: Object.assign(你要拷贝的对象,等待被拷贝的对象);
这种方法比较方便简洁,但是不会改变浅拷贝的本质

          Object.assign(o, obj);
          console.log(o);

深拷贝:拷贝多层,每一级别的数据都能拷贝

创建的对象的属性中包含数组与对象

  let obj = {
            name: 'cc',
            age: 17,
            color: ['red', 'pink', 'blue'],
            msg: {
                name: 'dog',
            }
        }

        let oo = {};

封装深拷贝函数

 function deepCopy(newobj, oldobj) {
            for (let k in oldobj) {
                //判断我们的属性属于哪种数据类型
                //获取属性值
                let item = oldobj[k];
                //判断是否是数组
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    //判断是否是对象
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    newobj[k] = item;
                }
            }
        }
        deepCopy(oo, obj);

        console.log(oo);

1、JSON.stringify()

JSON.parse(JSON.stringify(obj))是目前比较常用的深拷贝方法之一,它的原理就是利用JSON.stringify 将js对象序列化(JSON字符串),再使用JSON.parse来反序列化(还原)js对象。 这个方法可以简单粗暴的实现深拷贝,但是还存在问题,拷贝的对象中如果有函数,undefined,symbol,当使用过JSON.stringify()进行处理之后,都会消失。

let obj1 = {  a: 0,b: {c: 0}};
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.a = 1;
obj1.b.c = 1;
console.log(obj1); // {a: 1, b: {c: 1}}
console.log(obj2); // {a: 0, b: {c: 0}}

image.png