深拷贝和浅拷贝原理及实现方法
JavaScript数据类型分类
JavaScript数据类型分为普通数据类型和引用数据类型
1、普通数据类型包括:
(1)number:数值型
(2)string:字符型
(3)Boolean:布尔型
(4)null:空
(5)undefined:未定义
(6)es6新增:symbol
2、引用数据类型包括:
(1)array:数组
(2)object:对象
(3)function:函数
普通数据类型赋值都是直接赋值,如:
let a=0 let b=1 a=b
引用类型赋值(如对象、数组等)是拷贝地址,所以:
let obj={ uname:'张三', age:'12' } let obj2={} obj2=obj //当修改obj2或obj中的属性值,那么obj2和obj的值都会发生变化 obj.age=18 console.log(obj,obj2) //obj:{uname:'张三',age:'18'},obj2:{uname:'张三',age:'18'}
需求:将obj中的数据拷贝到o中,当修改o的属性值不影响obj中的属性值
一、浅拷贝
1、浅拷贝源代码:
let obj={ name:'aa', age:12, msg:{ index:2, pge:1 } } let o={} //浅拷贝,语法糖:Object.assign(o,obj) for(let k in obj){ o[k]=obj[k] } o.age=89 console.log(o,obj)//o:{uname:'aa',age:'89',msg:{index:2,pge:1}} obj2:{uname:'aa',age:'12',msg:{index:2,pge:1}}
原理:简单数据类型赋值是将数据进行传递,而复杂类型赋值是直接将存储复杂类型数据的地址进行传递,因此我们对复杂数据类型中的数据进行遍历从而使其成为简单数据类型的赋值
通过上述列子发现浅拷贝之后当修改name、age等数据时已不会影响到原来的数据,但当进行o.msg.index=5的操作时,obj中的index也会改变
o.msg.index=5 console.log(o,obj) //o:{uname:'aa',age:'89',msg:{index:5,pge:1}} //obj2:{uname:'aa',age:'12',msg:{index:5,pge:1}}
这是因为浅拷贝只会拷贝第一层数据,当我们的obj中包含了其他复杂数据类型时,则需要进行深拷贝
2、其他浅拷贝实现方法
//1.利用concat let a=[0,1,2,3] let b=[].concat(a)
//2.通过扩展运算符实现浅拷贝 let a=[1,2,3,4] let b=[...a] //或者[...b]=a
3.使用第三方库lodash
二、深拷贝
1、深拷贝源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | let obj={ name: 'aa' , age:12, msg:{ index:2, pge:1 },<br> arr:[ '1' , '2' , '3' ] } let o={} function deepCopy(newobj,oldobj){ for ( let k in oldobj){ //k为键值 let 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]=oldobj[k] } } } deepCopy(o,obj) o.msg.index=90 console.log(o,obj) |
2、其他深拷贝实现方法:
//通过json转换数据格式实现深拷贝
//缺点:针对对象的深拷贝,其中的方法和值为undefined的数据无法被拷贝,以及对时间等格式的数据处理会有些问题 let aa=[1,2,3,[4,[5]]] let bb=JSON.parse(JSON.stringify(aa))
//另外也可以通过JQuery的extend方法或者其他第三方库实现深拷贝
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通