浅谈一下js的浅拷贝和深拷贝

目录

一、什么是拷贝

二、浅拷贝和深拷贝概念

2.1 浅拷贝

代码

2.2深拷贝

代码

2.3 jQuery中的拷贝

三、深拷贝应用场景


一、什么是拷贝

谈到拷贝的话,大家应该是不陌生的,拷贝简单来说就是复制。

复制的话,这里就得想到js的两种数据类型:

1.基本数据类型:Number、String、null、undefined、Boolean。

2.引用数据类型:Object,Array

 对于基本数据类型的话,复制的是值,只有一层,叫浅拷贝,而对于引用数据类型,浅拷贝只能拷贝一层,更深层的只能拷贝地址,这就会造成修改拷贝后的值的时候,原来的数据可能也会变化,这就会破坏原数据。这就需要对数据进行深拷贝。

二、浅拷贝和深拷贝概念

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

深拷贝拷贝多层, 每一级别数据都会拷贝

2.1 浅拷贝

代码

<script>
        //浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用
  
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            }
        };
        var o = {};

        //1.直接赋值拷贝
        // o=obj;  

        //2.利用for...in 拷贝
        // for(var k in obj){    
        //     // k 是属性名 obj[k] 是属性值
        //     o[k]=obj[k];
        // }
        
        //3.利用es6的扩展运算符将对象展开进行拷贝
        // o={...obj}

        //浅拷贝方法
        Object.assign(o, obj)
        console.log(o);
<script>

这些方法都是浅拷贝的方法。

这里我们修改o对象的属性然后输出这o对象和obj对象

可以看出,修改了o对象的name属性,obj对象的name属性没有变化,但是修改o对象中的msg对象的age属性后,obj对象中的age属性也变了,这就是因为浅拷贝只拷贝一层,对更深层的对象或数组只能拷贝地址。

2.2深拷贝

  深拷贝拷贝多层,每一级数据都被拷贝。

可以利用函数的递归来实现,对每一层进行拷贝,一直到最后一层,那就是深拷贝了。

代码

<script>

var obj1 = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        };

        var o1 = {};

        //封装函数
        function deepCopy(newObj, oldObj) {
            for (var k in oldObj) {
                //判断属性值属于那种数据类型
                //1.获取属性值 oldObj[k]
                var item = oldObj[k];
                //2.判断这个值是否是数组
                if (item instanceof Array) {
                    newObj[k] = [];
                    deepCopy(newObj[k], item)
                } else if (item instanceof Object) {
                    //3.判断是否是对象
                    newObj[k]={};
                    deepCopy(newObj[k],item)
                }else{
                    //4.属于简单数据类型
                    newObj[k]=item;
                }  
            }
        }
        deepCopy(o1, obj1)
        o1.msg.age=15;
        console.log(obj1);
        console.log(o1);

</script>

对于对象的拷贝,通过函数的递归来实现,首先判断对象的属性属于那种数据类型,

1.判断是否是数组,是的话就赋值一个空数组,然后在递归调用该方法,传入这个空数组和属性,

2.判断是否是对象,是的话就赋值一个空对象,然后在递归调用该方法,传入这个空对象和属性,

3.当属性不是数组也不是对象的时候,就是基本数据类型了,直接赋值就行了。

像这样反复递归,最后都变为简单数据类型拷贝,就完成了对象的深拷贝。

从上面代码可以看出,修改o1.msg.age的值为15之后,obj1中的值没有变化,还是为18。

这就完成了对obj1 的深拷贝,也就是说,o1 对象完全复制了obj1 对象,变成一个独立的新对象,并不是多层只复制了地址。

2.3 jQuery中的拷贝

 在jQuery中也提供了一个方法可以进行对象的拷贝:$.extend 和 $.fn.extend 方法。

        var obj1 = {

        }
        var obj2 = {
            name: '1234',
            yh: true,
            ab: {
                a: 1
            }
        }
        //将后续参数克隆给参数1
        $.extend(obj1, obj2,{oo:123})
        obj1.ab.a = '我被改了'
        console.log('obj1', obj1);
        console.log('obj2', obj2);

 

可以看出,是将后面的参数都克隆到参数1上了,但是对obj1中的ab对象的a属性进行修改后,obj2的属性也被修改了,所以这是浅拷贝。

不过在这个方法的第一个参数填上 true之后就能变为深拷贝

        //不加true ,浅拷贝,加上true 深拷贝
        var obj1 = {

        }
        var obj2 = {
            name: '1234',
            yh: true,
            ab: {
                a: 1
            }
        }
        //将后续参数克隆给参数2
        $.extend(true,obj1, obj2,{oo:123})
        obj1.ab.a = '我被改了'
        console.log('obj1', obj1);
        console.log('obj2', obj2);

现在修改obj1中的属性,不会影响到obj2的属性了,变为对obj2的深拷贝了。

三、深拷贝应用场景

在前台发请求从后台获取数据的时候,获取的一般都是json格式的对象,我们一般要对这些数据进行操作,但是这些数据可能有其他地方也需要使用,就可能会造成很多隐性问题,对数据做一次深拷贝,就能让我们更安全的操作数据了,就不会出现原数据的破坏。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俗人844

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值