深拷贝和浅拷贝

本文介绍了JavaScript中浅拷贝和深拷贝的概念,通过示例代码展示了如何实现这两种拷贝方式,包括使用for循环、展开运算符、Object.assign以及递归方法。同时提到了JSON.stringify和parse的限制,以及如何通过判断拷贝后对象的属性关系来辨别拷贝类型。
摘要由CSDN通过智能技术生成

 浅拷贝: 创建一个新的对象,去拷贝另一个对象的 属性和属性值。 如果属性值是对象类型,只是把对象的地址拿过来用了。只是拷贝的第一层的属性,第二层用的还是原来的。

 深拷贝: 创建一个新的对象,去拷贝另一个对象的 属性和属性值。如果属性值是对象类型,就创建一个新的对象,拷贝这个属性值。依次类推 把对象所有深层次的 属性值都拷贝一遍。

浅拷贝

        let zhangsan = {
            name: 'zhangsan',
            child: {
                name: 'zhangsanfeng'
            }
        };

        // 拷贝一个zhangsan对象出来
        // let obj2 = {name:zhangsan.name}; 
        let obj2 = {};
        obj2.name = zhangsan.name;
        obj2.child = zhangsan.child;

        console.log(zhangsan);
        console.log(obj2);

        /*
        
        child:001 {name:'zhangsanfeng'}
        zhangsan    { name:zhangsan,child:001}
        obj2 {name:'zhangsan',child:001}
        */

        // obj2 是新创建的对象,地址和zhangsan不一样的 
        console.log(zhangsan === obj2);//false
        console.log(zhangsan.child === obj2.child);//true


        // 实现一个浅拷贝函数
        // 遍历一个对象的属性名和属性值 添加到 另一个新对象中

        function copy(o) {
            // 遍历一个o的属性名和属性值 添加到 另一个新对象中
            let newObj = {};
            for (let key in o) {
                let value = o[key];
                newObj[key] = value;
                // newObj[key] = o[key]
            }
            return newObj

        }
        let resObj = copy(zhangsan);
        console.log(resObj);
        //true
        console.log(resObj.child === zhangsan.child);

        /*
        zhangsan  = {
            name: 'zhangsan',
            child: 002
        }
        ...zhangsan  
            name: 'zhangsan',
            child: 002

        
        */
        //    展开运算符实现 浅拷贝
        let obj3 = { ...zhangsan };
        console.log(obj3);
        console.log(obj3.child == zhangsan.child);

        //   Object.assign浅拷贝
        let obj4 = {}
        Object.assign(obj4, zhangsan);
        console.log(obj4 === zhangsan);//false
        console.log(obj4);
        console.log(obj4.child == zhangsan.child);//true

深拷贝

递归实现方法

        let obj1 = {
            name: 'zhangsan',
            child: {
                name: 'zhangsanfeng'
            }
        };
        // obj1.child.father = obj1
        // console.log(obj1);


        let m = new Map() //存的数据,会影响垃圾回收机制
        let wm = new WeakMap()// 存的数据 是一种弱引用(不会影响垃圾回收机制)
        // wm.set()
        // wm.get()
        // wm.has()


        function deepCopy(obj) {
            let newObj = {};
            //遍历obj的属性名和属性值 都添加到newObj中,如果属性值是一个对象,做判断,再创建给新对象,把属性值对象key和value添加到 新对象中
            for (let key in obj) {
                let value = obj[key]
                if (typeof value == 'object') {
                    // 如果是 创建要给新的value ,和 value 一样
                    // 调用自己
                    let newValue = deepCopy(value);
                    newObj[key] = newValue;
                } else {
                    // 如果属性不是对象,就直接存入新对象中
                    newObj[key] = value;

                }
            }
            return newObj;
        }

        let resObj = deepCopy(obj1)
        console.log(resObj === obj1);
        console.log(resObj.child === obj1.child);

其他实现方法

        //2-种
        // JSON.stringify  parse
        let obj1 = {
            name: 'zhangsan',
            child: {
                name: 'zhangsanfeng',
            }
        };
        obj1.child.father = obj1
        console.log(obj1);


        // 循环引用会报错
        let str = JSON.stringify(obj1);
        console.log(str);
        // JSON.parse 内部会创建一个新对象,放字符串里面的属性名和属性值
        let obj2 = JSON.parse(str);
        console.log(obj2);
        console.log(obj2 == obj1);
        console.log(obj2.child == obj1.child);
        // 缺点:json数据的类型 有限制--不能存函数
        // 如果拷贝的对象 存在循环引用 就会报错

判断深浅拷贝的方法

        let obj1 = {
            name: 'zhangsan',
            child: {
                name: 'zhangsanfeng',
                // father:
            }
        };
        obj1.child.father = obj1
        console.log(obj1);
        let obj2 = _.clone(obj1);
        console.log(obj2);

        // 说明是拷贝
        console.log(obj2 === obj1);//false
        // 说明是浅拷贝
        console.log(obj2.child === obj1.child);//true


        let obj3 = _.cloneDeep(obj1);
        console.log(obj3);//

        // 说明是拷贝
        console.log(obj3 === obj1);//false
        // 说明是深拷贝
        console.log(obj3.child === obj1.child);//false
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值