jQuery的深浅拷贝

<script src="./jquery.min.js"></script>
<script>
    /*
    深浅拷贝 
        
        复制 , 引用数据类型时 (主要是对象和数组) 才会考虑深浅拷贝问题

        浅拷贝 --- 拷贝复制引用数据类型的存储地址
                执行浅拷贝,执行的变量之间,相互有关联
                一个操作修改存储的数据内容,另一个也会影响

        深拷贝 --- 拷贝复制引用数据类型的具体数值
                执行深拷贝,执行的变量之间,相互没有关联
                一个操作修改存储的数据内容,另一个不会影响
    
    */


    // 所谓浅拷贝

    // 定义的引用数据类型
    const obj1 = {
        name : '张三',
        age : 18,
        sex : '男',
        addr : '北京',
    };

    // 执行浅拷贝
    // 直接将引用数据类型的地址,赋值给另一个变量
    // 实际上是将obj1的地址,赋值给obj2存储
    // 此时 obj2和obj1 存储的是相同的 内存地址
    // 就相当于 obj2 和 obj1 操作的是相同的 内存地址
    
    const obj2 = obj1;

    // 通过obj2 ,修改 存储的数据单元
    obj2.name = '李四';

    // 查看存储的内容,obj1和obj2都是修改之后的内容
    console.log(obj2);
    console.log(obj1);

    // 相当于,一个银行账户,通过 存折 和 银行卡 或者 手机 都可以操作
    // 任意一个操作,都会影响账户中存储的金额数值
    //


    // 所谓的深拷贝,是循环遍历 数组 对象 中的数据,只复制拷贝数据内容

    const obj3 = {
        name : '张三',
        age : 18,
        sex : '男',
        addr : '北京',
    };

    const obj4 = {};

    for(let key in obj3){
    //     // 将 obj3 的键名,作为obj4的键名
    //     // 将 obj3 的数值,作为obj4的数值
    //     // 也就是将 obj3的键名数值,复制拷贝给 obj4
        obj4[key] = obj3[key];
    }

    console.log(obj3);
    console.log(obj4);

    // obj3 和 obj4 是两个独立的引用数据类型,两个独立的变量
    // 任意一个变量,修改存储的数值,对另一个变量,不影响

    // obj4.name = '王二麻子';

    // 总结:
    // 浅拷贝 : 只复制拷贝 引用数据类型的 内存地址
    //          两个变量之间有联系
    //          一个操作,另一个也改变
    // 深拷贝 : 只复制拷贝 引用数据类型的 数值数据内容
    //          两个变量之间没有联系
    //          一个操作,另一个不改变
    // 实际项目中,深浅拷贝都要用到,具体要看实际项目需求
    
    // 有待解决的问题:
    // 如果 单元中存储的是 多维的数组或者对象数据,只是简单的循环遍历无法解决
    // 例如 [1,2,3,[4,5,6,7,8,9]]
    // 这样一个多维数组,如果只是简单的循环遍历
    // 那么其中的 二维数组 执行的 仍然是 浅拷贝
    // 当遇到 二维甚至多维数组对象时, 要再次执行循环遍历

    // 第一次获取到数值1,复制赋值1
    // 第二次获取到数值2,复制赋值2
    // 第三次获取到数值3,复制赋值3
    // 第四次获取到数组[4,5,6],复制的是数组[4,5,6]的内存地址
    // 此时,应该再次循环遍历数组[4,5,6],获取其中的数值数据,而不是简单的复制内存地址
    // const arr = [1,2,3,[4,5,6]];
    // 理论上应该再次循环
    // 实际操作中,应该使用递归完成

    // 在jQuery中给我们提供了深拷贝的方法,我们直接使用就可以了

    // $.extend()  深浅拷贝方法
    // $.extend(参数1 , 参数2 , 参数3 , 参数4 ,参数5 ..);
    // 将 参数2 之后的内容,都拷贝到参数2中
    // 执行的拷贝方式,就是参数1,设定的拷贝方式
    // 参数1: 是否深拷贝,默认值是 false , 也可以不写
    //        默认执行的是浅拷贝效果
    //        设定为 true 

    const obj = {
        id : 1,
        userName : 'zhangsan',
        userPwd : '123456',
        phone : '12345678901',
        data : {
            sex : '男',
            age : 18,
        }, 
    };

    const newObj = {};

    // 默认值是false,或者不写
    // 默认执行的是浅拷贝
    // 如果存储的是基本数据类型,拷贝之后,两个变量之间的操作,相互不会影响
    // 如果存储的是引用数据类型,拷贝之后,两个变量之间的操作,相互会影响
    $.extend(newObj , obj);

    // 如果设定参数1为 true
    // 执行的是深拷贝
    // 如果存储的是引用数据类型,拷贝之后,两个变量之间的操作,相互不会影响
    $.extend(true , newObj , obj);


    // 修改id存储的数据,存储的是基本数据类型,相互不会影响
    obj.id = 100;
    // 修改data存储的数据,存储的是引用数据类型,相互会影响
    obj.data.sex = '女';

    console.log(newObj);
    console.log(obj);

    // 特别说明:
    // 在 jQuery 的 $.extend()  
    // 所谓的深浅拷贝,值得是,针对于,二维甚至多维的设定
    // 默认第一维,执行的都是深拷贝,而且不能设定,不能修改
    // 所谓的参数1,针对的是,第二维甚至是之后的第三四维等的深浅拷贝的设定
    // 如果要想直接浅拷贝,你直接 newObj = obj 就可以了,都没必要用 extend()

    // 如果使用原生js,是写一个递归函数
    // 判断数据类型如果是 数组 或者 对象
    // 调用函数本身,再次执行一个深拷贝
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值