【JS】深拷贝与浅拷贝,用递归实现深拷贝

js中的深浅拷贝的区别主要是针对Object和Array这种复杂类型的数据而言的。简单来说,浅拷贝只复制最外层的数据,对于更深层级的数据复制的是地址,复制前后的数据指向相同的存储地址。而深拷贝复制了所有层级的数据。

一 浅拷贝

复制最外层的数据,对于更深层级的数据复制了地址,将对象oldObj拷贝给对象newObj后,修改newObj中的属性,oldObj中的内容也会跟着变化。

<script>
        var oldObj = {
            id: 1,
            name: 'ammy',
            contact: {
                tel: 10086,
                wechat: 'hello10086'
            },
            hobby: ['sing', 'dance', 'sports']
        };
        var newObj = {};
        for(var k in oldObj) {
            // k为属性名,oldObj[k]为属性值
            newObj[k] = oldObj[k];
        }
        console.log(newObj);
    </script>

在这里插入图片描述
从结果来看,是将对象型属性msg也拷贝了。但是,这样拷贝会存在一个问题,当修改newObj中的属性时,oldObj中的内容也会跟着改变。

 newObj.contact.tel = '10000';
 console.log(oldObj);

在这里插入图片描述
从拷贝结果可以看出,当修改newObj中的msg中的tel属性为10000时,oldObj中的属性也发生了改变。

这是因为JavaScript 存储对象都是存地址的,浅拷贝对于更层级的数据拷贝的是地址。将oldObj中msg的地址拷贝给newObj,newObj中msg的地址仍然指向仍然是原来obj中的地址,即拷贝前后的msg指向的是同一个地址,因此修改newObj中的数据会影响oldObj中的数据。

ES6中新增了浅拷贝的语法,Object.assign(newObj,oldObj),相比上述方法简洁许多。

二 深拷贝

深拷贝,递归拷贝每一层级的数据,将值赋值给对应的属性。修改拷贝后的newObj不会对oldObj产生影响。

function deepCopy(target, source) {
            for (var k in source) {
                // 获取属性值
                var item = source[k];
 // 判断,数据类型为复杂数据类型Array和Object时,进行递归复制,为简单数据类型时才能进行直接赋值拷贝。
                if (item instanceof Array) {
                    target[k] = [];
                    deepCopy(target[k], item);
                } else if (item instanceof Object) {
                    target[k] = {};
                    deepCopy(target[k], item);
                } else {
                    target[k] = item;
                }
            }
        }
        deepCopy(newObj,oldObj);
        console.log(newObj);
        // 修改newObj属性
        newObj.contact.tel = '10000';
		console.log(oldObj);

注:由于Array也属于Object,因此判断时应先判断是否为Array类型再判断是否为Object类型。

在这里插入图片描述
从结果可以看出,深拷贝修改newObj的属性后oldObj中的内容并没有发生改变。在拷贝的过程中,通过判断数据类型对复杂数据进行递归复制,将值复制给对应的属性,从而成功复制每一层级的数据。

三 总结

浅拷贝只复制最外层的数据,对于更深层级的数据复制的是地址,复制前后的数据指向相同的存储地址。深拷贝复制所有层级的数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值