当前位置: 首页 > Web前端 > JavaScript

理解深拷贝和浅拷贝

时间:2023-03-27 13:09:56 JavaScript

前置知识:常用数据类型:基本类型:String/Number/Boolean/Null/Undefined引用类型:Function/Object/Array知识:vara=123=>左边的常量a是栈,123右边是堆,stack指向堆的概念:浅拷贝:创建一个新的对象,这个对象会记住一份原对象的属性值的副本如果属性是基本类型,那么基本类型的值为copied如果属性是引用类型,则复制内存地址深度Copy:从内存中完整复制一个对象,在堆内存中开辟一块新区域存放新对象,以及对新对象的修改不会影响原始对象浅拷贝和赋值的区别varperson={name:"LoveisAword",hobby:['study',['watchingamovie','shopping'],'running'],date:newRegExp('\\w+')function(){}}赋值:当我们把一个对象赋值给一个新的变量时,就是实际只是对象在栈中的地址,而不是堆中的数据。即即使是两个对象也指向同一个存储空间。无论哪个对象发生变化,实际上都是变化的存储空间的内容varperson1=personperson1.name='XiaoxingWang'preson1.hobby[0]='playing'console.log(preson)console.log(person1)=====>相同的结果浅拷贝:重新创建堆中的内存。复制前后对象的基本数据类型不会相互影响,但是复制前后对象的引用类型会相互影响,因为它们共享同一块内存。functionshallowCopy(obj){vartarget={}for(variinobj){if(obj.hasOwnProperty(i)){target[i]=obj[i]}}returntarget}varperson1=shallowCopy(person)person1.name="XiaoxingWang"//基本数据类型,基本数据类型互不影响person1.hobby[0]='play'//这里是引用数据类型数组,所以复制前后的对象会互相影响。console.log(person)console.log(person1)深拷贝从堆内存区创建一个新的用于存储新对象,递归复制对象中的子对象,复制前后两个对象互不影响functiondeepClone(obj){varcloneObj={}if(obj===null)returnobj//typeOf去toconsole.lognull,出现的也是obj对象if(objinstanceofDate)returnnewDate(obj)//instanceof用来判断左边是不是右边类的实例Date的propertype在obj的原型链上)if(objinstanceofRegExp)returnnewRegExp(obj)if(typeOfobj!=='object')returnobjfor(variinobj){if(obj.hasOwnProperty(i)){cloneObj[i]=deepClone(obj[i])}}returncloneObj}varperson1=deepClone(person)varperson1=JSON.parse(JSON.stringify(person))//正则RegExp和函数json.parse和深拷贝不同person1.name="王小星"person1.hobby[0]='play'console.log(person)console.log(person1)