JavaScript 浅拷贝与深拷贝概念及应用 Jquery的浅拷贝和深拷贝

目录

1. 浅拷贝概念

浅拷贝的例子1:for  in  进行浅拷贝

浅拷贝的例子2:定义数组进行浅拷贝

浅拷贝的例子3:利用Object.assign()方法进行拷贝

2. 深拷贝

3. 浅拷贝和深拷贝的应用:

4. jQuery的深拷贝和浅拷贝extend


1. 浅拷贝概念

针对复杂的数据类型,单独开辟新的内存空间,在栈里面会有地址指向这个空间,拷贝地址

浅拷贝:改变旧的对象的复杂数据类型的值,新的对象的对应值也会改变,借用一个博主的话,拷贝以后复杂数据类型不能够自食其力,就叫浅拷贝。

注意:深浅拷贝概念只针对于 复杂数据类型,数组、对象、函数。

浅拷贝的例子1:for  in  进行浅拷贝

        var obj = {
            name: 'a',
            msg: {
                age: 18,
            }
        }
        var o = {};
        for (var k in obj) {
            o[k] = obj[k];
        }
        console.log(o); // age是19 name还是a
        obj.name = 'b';
        obj.msg.age = 19;
        console.log(obj); // age是19 name是b
        console.log(o); // age是19 name是a

修改了obj的msg对象的age值,o对象的也发生变化,复杂数据类型无法自食其力

修改了obj的name值,o对象的没有发生变化,基本数据类型能够 “自食其力”

浅拷贝的例子2:定义数组进行浅拷贝

        let a = [1, 2, 3, 4, 5];
        let b = a;
        a[0] = 3;
        console.log(a); // [3, 2, 3, 4, 5]
        console.log(b); // [3, 2, 3, 4, 5]
        console.log(a === b); // true
       

 总结:

1. a数组赋值给了b数组
2. 紧接着修改a数组的一个值,b的数组也相应的变化,这个也是浅拷贝?这里存疑

浅拷贝的例子3:利用Object.assign()方法进行拷贝

        // assign
        let obj11 = {
            name: 'Lily',
            age: '20',
            time: ['13', '15'],
            person: {
                name: 'Henry',
                age: '21'
            }
        };
        let obj12 = {
            age: '22'
        };
        let obj13 = Object.assign({}, obj11, obj12);
        // 1. 为什么age是22?obj11和obj12都是拷贝源,如果冲突 后面会覆盖前面的
        console.log(obj13); 
        // 2. 不会改变obj11的age
        obj13.age = '25'; 
        console.log(obj11.age); // 20
        // 3. 会改变obj11的person.age
        obj13.person.age = '25'; // 
        console.log(obj11.person.age); //25
        // 4. 会改变obj11的time值
        obj13.time[1] = '25'; // 
        console.log(obj11.time[1]); // 25

首先明确,assign可以有多个参数,第一个永远是目标对象,后面的对象是拷贝来源。

但是注意!

1. 当obj01和obj02都有基本数据类型age时,后面覆盖前面

2. 基本数据类型obj13的age改变了,不会影响obj01的age值。

3. obj13.person.age的值改变了以及obj13.time[1]的值改变了,因为是复杂数据类型对象和数组,所以都会影响obj11和obj12的值。

浅拷贝的例子4:对象的浅拷贝

        // 1、 直接赋值 是浅拷贝 数据绑定
        let obj01 = {
            name: 'Lily',
            age: '20',
            time: ['13', '15'],
            person: {
                name: 'Henry',
                age: '21'
            }
        };
        let obj02 = obj01; // 直接赋值是浅拷贝
        obj02.age = '25'; // 25 会改变obj01的age 无法自食其力
        console.log(obj01.age);
        obj01.name = '你好'; 
        console.log(obj02.name); // '你好'无法自食其力 
        obj02.person.age = '25'; //会改变obj01的person.age
        console.log(obj01.person.age); // 25
        obj02.time[1] = '25'; //会改变obj01的time值
        console.log(obj01.time[1]); // 25

注意对象在利用let进行拷贝赋值,也是浅拷贝

但是!,obj01.name和age改变时,也会影响obj02,本来基本数据类型应该是可以自食其力不受影响的。我也给整蒙了,明天再思考。有没有小伙伴出处注意呢?

2. 深拷贝

概念:

newObj拷贝了oldObj的值,拷贝之后,修改newObj的复杂数据类型值,oldObj的复杂数据值不会改变。能够自食其力

        逻辑

        1. 先判断对象里的元素是数组吗?

        1.1 如果是,新对象里面的对应属性的属性值,让其创建一个新数组,递归

        1.2 如果不是数组,再判断是不是对象,如果是,新对象对应的属性值,让其创建一个新对象,递归

        2. 递归点, oldObj的属性值赋值给newObj对应的属性,newObj[k] = item;

        var furn = {
            size: '10',
            msg: {
                size: '100',
                msg: {
                    size: '1000'
                }
            }
        };
        function deepCopy(newObj, oldObj) {
            for (var k in oldObj) {
                var 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;
                }
            }
            return newObj;
        }
        console.log(deepCopy(furn));

最终输出的结果,是拷贝之后的元素

另一种写法

        function DeepClone(obj) {
            if (typeof obj !== 'object' || obj === null) {
                debugger
                return obj
            }
            debugger
            let result = Array.isArray(obj) ? [] : {}
            for (let key in obj) {
                debugger
                if (obj.hasOwnProperty(key)) {
                    // 保证key不是原型的属性
                    result[key] = DeepClone(obj[key])
                    debugger
                }
            }
            return result
        }

3. 浅拷贝和深拷贝的应用:

        后台返回一些数据,需要对这些数据进行操作:比如增加、删除、修改、查询等,即便复制了数据对象,

        如果是浅拷贝,复杂数据类型,拷贝后修改仍然会影响oldObj

        深拷贝,不会影响,更加安全

4. jQuery的深拷贝和浅拷贝extend

如果不加参数,【记住,不加参数,而不是写false】,就是浅拷贝,复杂数据类型是传递地址,拷贝的是地址,拷贝之后新对象不能够自食其力

        var oldObj = {
            name: 'jmq',
            msg: {
                age: 20
            }
        }

        var newObj = {};
        // 1. 浅拷贝
        $.extend(newObj, oldObj);
        console.log(newObj); // jmq 19
        oldObj.name = 'syc';
        oldObj.msg.age = '19';
        console.log(oldObj); // syc 19
        console.log(newObj); // jmq  19

如果加了参数,true,就是深拷贝,拷贝复杂数据类型,新旧复杂数据类型指向的是不同的地址,不会同时改变

        $.extend(true, newObj1, oldObj1);
        console.log(newObj1); // jmq 20
        oldObj1.name = 'syc';
        oldObj1.msg.age = '19';
        console.log(oldObj1); // syc 19
        console.log(newObj1); // jmq 20

参考文章:

感觉下面这个博主写的特别的详细

js实现数组浅拷贝和深拷贝_xm1037782843的博客-优快云博客_js 数组深拷贝

个人学习id:201903090124-26

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值