js中数组对象的深浅拷贝

  1. 浅克隆
    (1)对象的浅克隆:
    <script>
        //=>浅克隆:只复制对象或者数组的第一级内容
//=>深克隆:克隆后数组的每一级都和原始数组没有关联
//那么请说出,浅克隆都怎么去实现,如何实现深度克隆
    let obj = {
        a: 100,
        b: [10, 20, 30],
        c: {
            x: 10
        },
        d: /^\d+$/
    };

    let arr = [10, [100, 200], {
        x: 10,
        y: 20
    }];
    //第一种浅克隆
    let newObj={...obj};
     
    //第二种浅克隆
    let newObj=Object.assign({},obj);

    //第三种
    //for in在遍历对象的时候,遍历是当前对象可枚举(列举)的属性
    //私有属性(除一些特殊的内置属性是不可枚举的)
    //公有属性(大部分都是不可枚举的,但是自己在类原型上扩展的是可枚举的)
    //由下面的(2)也说明在遍历的过程中,很可能遍历到共有的属性方法,所以for in 循环的时候,我们需要判断是否为私有的
    let newObj={};
    for(let key in obj){
        if(!obj.hasOwnProperty(key)) break;
        newObj[key]=obj[key];
    }
    console.log(newObj,obj)
    </script>

在这里插入图片描述
for in 和 for of
在这里插入图片描述
自定义类的遍历
在这里插入图片描述
(2)数组的浅克隆

    <script>
        let arr = [10, [100, 200], {
            x: 10,
            y: 20
        }];
        //第一种
        let newArr=[...arr];
        //第二种
        let newArr=Object.assign([],arr);
        //第三种
        let newArr=arr.map(item=>item);
        //第四种
        let newArr=arr.slice();
        //第五种
        let newArr=arr.concat([]);

        console.log(newArr,arr); //newArr==arr false newArr[1]==arr[1] true
    </script>
  1. 深克隆
    (1)
    方案1:整体变为字符串,在重新变为对象,这样浏览器会重新开辟全套的内存空间存储信息。 JSON.stringify / JSON.parse。
    此方案存在BUG:把对象中的某些属性值变为字符串,会存在问题。
    正则变为{}
    日期对象变为日期字符串
    Symbol/BigInt/function/undefined 等会消失
    所以这种方案只适用于数据中只有“number/string/boolean/null/普通对象/数组对象”等内容的时候。
    对象:
    <script>
        let obj = {
            a: 100,
            b: [10, 20, 30],
            c: {
                x: 10
            },
            d: /^\d+$/
        };      
        let newObj=JSON.parse(JSON.stringify(obj));  
    </script>

在这里插入图片描述

数组:

    <script>
        let arr = [10, [100, 200], {
            x: 10,
            y: 20
        }];
        let newArr=JSON.parse(JSON.stringify(arr));
        console.log(newArr,arr);        
    </script>

(2)方案2:一层层遍历

    <script>
        let obj = {
            a: 100,
            b: [10, 20, 30],
            c: {
                x: 10
            },
            d: /^\d+$/,
            e:Symbol('AA'),
            f:new Date(),
            g:function(){},
            h:undefined,
            i:null
        }; 
        obj.name=obj;
        function cloneDeep(obj){ 
            let type=typeof obj;         
            //如果传递的不是对象类型,直接返回对应的值(基本类型/函数/Symbol/BigInt)
            if(obj===null) return null;
            if(type!=="object" && type!=="function") return obj;
            //结果是正则或者日期函数,我们创建一个值类似但是不同实例的结果出来
            if(/^(RegExp|Date)$/i.test(constructor.name)) return new constructor(obj);
             //获取当前值的构造函数:获知它的类型
             let constructor=obj.constructor;               
            //创建对象的新实例:新数组或者新对象
            let clone=new constructor;
            for(let key in obj){
                if(!obj.hasOwnProperty(key)) break;
                //为了避免对象中的某个属性用的还是对象,导致的循环嵌套(死递归)
                if(obj===obj[name]){
                    clone[key]=obj[key];
                    break;
                }
                clone[key]=cloneDeep(obj[key]);
            }
            return clone;
        }
        // let newObj=JSON.parse(JSON.stringify(obj));  
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值