js深拷贝与浅拷贝

js数据类型

基本数据类型String,Number,Boolean,Null,undefined
引用类型Object(Array、Function、Array、Date、RegExp)
基本数据类型存在于栈区,例如var a=1;
在这里插入图片描述
在拷贝时,例如 var b=a; 栈中会重新为b开辟一个内存,如图
在这里插入图片描述
所以当a改变时,并不影响b的值;因此基本数据类型并不存在深拷贝和浅拷贝的问题;

引用类型存在于堆中,例如var obj1 = [0,1,2,3]; 栈区中存储变量名及堆地址,堆地址指向堆中的数据;如图:
在这里插入图片描述
当进行拷贝时,例如var obj2 = obj1; obj2拷贝的是obj1存放数据的堆地址,所以当obj1中的数据改变时,obj2拷贝的堆地址并没有发生变化,obj2的数据也会随着obj1数据的变化而变化。
在这里插入图片描述
上述举例说明,浅拷贝与深拷贝只针对于引用类型数据;

先做简单的深拷贝与浅拷贝的描述,后续会继续做深化描述:设置变量A,B,为A赋值,再将A(源对象)赋给B(拷贝对象),当源对象数据改变时,拷贝对象数据也随之改变,称为浅拷贝,当源对象数据改变,而拷贝对象数据不随之改变时,称为深拷贝。

浅拷贝实现方法

1.直接赋值

let obj1={
        id:2179,
        info:{
            name:"活着",
            price:79,
            author:"余华"
        }
    }
    let obj2 = obj1;
    obj1.id = 1928;
    console.log(obj1.id,obj2.id);  //1928   1928

2.Object.assign

let obj1={
        id:2179,
        info:{
            name:"活着",
            price:79,
            author:"余华"
        }
    }
    let obj2 = Object.assign({},obj1);
    obj1.id = 1928;
    obj1.info.price = 97;
    console.log(obj1,obj2);

在这里插入图片描述
只深拷贝了第一层,内层直接引用,属于浅操作,扩展运算符同理,不再举例叙述

深拷贝实现方法

1.jQuery—extend(true, …) 第一个参数必须设置为true,才能实现深拷贝,默认为false

let obj1={
     id:2179,
     info:{
     name:"活着",
     price:79,
     author:"余华"
     }
     }
     let obj2 = $.extend(true,{},obj1);
     obj1.id = 1928;
     obj1.info.price = 101;
     console.log(obj1,obj2);

在这里插入图片描述
内外层均实现了深拷贝

2.JSON.parse(JSON.stringify(…))
原理:将对象字符串化再转化为JSON对象,产生了新的对象

let obj1={
        id:2179,
        info:{
            name:"活着",
            price:79,
            author:"余华"
        }
    }
    let obj2 = JSON.parse(JSON.stringify(obj1));
    obj1.id = 1928;
    obj1.info.price = 101;
    console.log(obj1,obj2);

在这里插入图片描述
3.递归拷贝

 function deepCopy(obj){
        var obj2 = Array.isArray(obj)?[]:{};
        if(obj && typeof obj == "object"){
            for(var i in obj){
                if(obj.hasOwnProperty(i)){
                    if(i && typeof obj[i] == "object"){
                        obj2[i] = deepCopy(obj[i]);
                    }else{
                        obj2[i] = obj[i];
                    }
                }
            }
        }
        return obj2;
    }

     let obj1 = {
         a:1,
         b:2,
         c:{
             c1:"c-1",
             c2:"c-2",
             c3:{
                 c31:"c3-1",
                 c32:"c3-2"
             }
         }
     };

     let obj2 = deepCopy(obj1);
     obj1.a = "1-modify";
     obj1.c.c1 = "c-1-modify";
     obj1.c.c3.c31 = "c3-1-modify";
     console.log(obj1, obj2);

在这里插入图片描述

总结
浅拷贝:拷贝对象只是拷贝了源对象的第一层,内层直接引用源对象数据;
深拷贝:拷贝对象对源对象从外到内每一级别都进行了拷贝。

***************2023/01/30补充
js内置深拷贝方法:structuredClone
各种深拷贝方法对比参考:https://www.builder.io/blog/structured-clone

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值