原生JS【数据深浅克隆】

数据浅克隆

// Object.assign()=>用于将所有可枚举属性的值从一个或多个原对象复制到目标对象中,然后返回目标对象
        // 语法:Object.assign(target,...sources)【target:目标对象】,【sources:原对象(多个参数)】
        // 例子:
        let obj1={
            a:1,
            b:2,
            c:3
        };
        let obj = Object.assign({},obj1,{d:4,e:5})
        console.log(obj); //{a: 1, b: 2, c: 3, d: 4, e: 5}

        // 例子2:如果是字符串将自动被转为对象,其他会被忽略
        const v1='abc';
        const obj=Object.assign({},v1);
        console.log(obj);// { "0": "a", "1": "b", "2": "c" }

        const v2 = true;
        const v3 = 10;
        const v4 = undefined;
        const v5 = null;
        const obj1 = Object.assign({}, v1,v2,v3,v4); 
        console.log(obj1);   // { "0": "a", "1": "b", "2": "c" }
// 克隆整个函数
        function shallowClone(a){
            const obj={};//定义一个空对象储存每个数据,不允许再次修改
            for(let i in a){
                obj[i]=a[i];
            }
            return obj;
        }
        // 被克隆的对象
        const oldObj={
            a:1,
            b:['1','2','3'],
            c:{
                d:{i:2}//新对象修改的属性值也会影响到被克隆对象相应的属性值
            }
        };
        const newObj = shallowClone(oldObj);//将克隆出来的新对象地址指向被克隆的对象地址
        console.log(newObj.c.d,oldObj.c.d);
        console.log(oldObj.c.d===newObj.c.d);//true

        数据浅克隆带来的影响:因为对象只会被克隆到最外部的一层,要克隆更深层的对象,则仍然是通过引用指向同一块堆内存

        简而言之,当我对克隆出的对象做修改时,也会影响到被克隆的对象=>占用了不必要的内存空间(内存泄漏)

数据深克隆 

        // JOSN.parse(text,reviver)
        // text:必选参数,一个有效的JS字符串;
        // reviver:可选参数,一个转换结果的函数。如果成员包含嵌套对象,则先于父对象转换嵌套对象。对于每个成员,会发生以下情况:
        // 1.如果reviver返回一个有效值,则成员值将替换为转换后的值
        // 2.如果reviver返回它接收的相同值,则不修改成员值
        // 3.如果reviver返回null或undefined,则删除成员
        // 返回值:一个对象或数组
        // 注意:
        // 1.属性名必需是双引号括起来的字符串,最后一个属性后不能有逗号。
        // 2.数值禁止出现前导零 (JSON.stringify 方法自动忽略前导零,而在 JSON.parse 方法中将会抛出 SyntaxError)。
        // 3.只有有限的一些字符可能会被转义;禁止某些控制字符;Unicode行分隔符(U+2028)和段分隔符(U+2029)被允许;字符串必需用双引号括起来。

        // SON.stringify()   
        // JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
        // 语法:JSON.stringify(value[, replacer[, space]])
        // value:必需, 要转换的 JavaScript 值(通常为对象或数组)。
        // replacer:可选。用于转换结果的函数或数组。
        // 如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
        // 如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
        // space:可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
       

        // 例题:JSON序列化方法
        const oldObj = {
            a: 1,
            b: ['1', '2', '3'],
            c: {
                d: {
                    i: 2
                }
            }
        };
        const newObj = JSON.parse(JSON.stringify(oldObj));
        console.log(newObj.c.d, oldObj.c.d); //{i:2}{i:2}
        console.log(newObj.c.d === oldObj.c.d); //false
        newObj.c.d.i = 'change';
        console.log(newObj.c.d, oldObj.c.d); //{i:'change'}{i:2}

  JSON.parse()的坑:
        1.无法实现对函数、RegExp、稀疏数组等特殊对象的克隆
        2.会抛弃对象的constructor,所有的构造函数都会指向Object原型
        3.对象有循环引用时就会报错

 // 例题2:
            // hasOwnProperty()
            // 定义:用于检测对象是否包含某些属性的方法,返回一个布尔值

            let data1 = {c:1,d:2,f:{e:{i:2}}}
            // 定义一个函数用来判断克隆的对象的数据类型是否符合
            function isArray(arr){
                return Object.prototype.toString.call(arr)==='[object Array]'
            }
            function deepClone(obj){
                // 如果obj是原始数据类型就直接返回
                if(typeof obj !== 'object'&& typeof obj !== 'function'){
                    return obj;  
                }
                var a = isArray(obj)?[]:{};//判断obj的原型是否指向数组类型
                for(i in obj){
                    // 判断obj对象师傅包含[i]属性
                    if(obj.hasOwnProperty(i)){
                        // 检测obj原型的[i]属性是否是一个对象类型
                        a[i]=typeof obj[i] === 'object'?deepClone(obj[i]):obj[i];
                    }
                }
                return a;
            }
            let data1Clone=deepClone(data1);
            console.log(data1,data1Clone);
            console.log(data1Clone.f.e===data1.f.e);//false
            data1Clone.f.e.i='change';
            console.log(data1Clone.f.e,data1.f.e);//{i:'change'}{i:2}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值