前言本文介绍的是浅拷贝和深拷贝涉及的知识点。工作中很重要,面试时一定要考。希望对朋友们有所帮助!为什么会有深拷贝和浅拷贝?首先我们要知道一个过程1.对象属于引用类型。之后浏览器会为其开辟一个新的内存空间,并为其分配一个十六进制地址2.按照一定的顺序,将对象的键值对存储在内存空间中3,将开辟的内存地址分配给变量(或事件),然后变量会通过地址找到内存空间,然后操作基本数据类型和引用数据类型。数据分为基本数据类型和引用数据类型。基本数据类型String,Number,Boolean,Null,Undefined,Symbol基本数据类型是直接存储在栈中的数据letstr1='123';str2=str1;str2='456';控制台日志(str1);//'123'console.log(str2);//'456'图像示例:之前买了一双鞋子,现在又买了一双,如果其中一双坏了,不会影响另一双引用数据类型Array和Object引用数据类型存储的是什么就是栈中引用了对象,真正的数据存放在内存中letarr1=[1,2,3,4,5,6];arr2=arr1;arr2.pop();console.log(arr1);//[1,2,3,4,5]console.log(arr2);//[1,2,3,4,5]图像示例:在草原上,一些羊吃了烂草生病了死了。草原还是草原,只是内部的草变少了;羊群仍然是羊群,但内部的羊少了。深拷贝和浅拷贝的概念浅拷贝:只拷贝对象的引用,不拷贝对象本身,将对象引用的所有对象都拷贝一遍。深拷贝和浅拷贝的区别~以及原始数据是否指向同一个对象。第一层数据是基本数据类型。原始数据包含子对象。赋值会一起改变数据。原数据会一起变ShallowcopyNoChange不会导致原数据一起变Change会让数据一起变DeepcopyNoChange不会导致原数据一起变Change不会导致原数据一起变浅拷贝一般循环constarr1=[1,2,['ming','abc'],5];constshallowClone=(arr)=>{constdst=[];for(letpropinarr){if(arr.hasOwnProperty(prop)){dst[prop]=arr[prop];}}returndst;}constarr2=shallowClone(arr1);arr2[2].push('wuhan');arr2[3]=5;console.log(arr1);console.log(arr2);运行结果:object.assign()Object.assign()方法可以将源对象本身的任意数量的可枚举属性复制到目标对象,然后返回目标对象Object.assign()执行浅拷贝,复制对象的引用属性,不是对象本身constobj1={username:'ming',skill:{play:['backetball','game'],rend:'book',},girlfriends:['xiaomi','xiaohong','小兰'],};constobj2=Object.assign({},obj1);obj2.username='memg';//修改基本类型obj2.skill.read='e-mail';//修改第二层基本类型obj2.skill.play=['footbool'];//修改第二层的引用类型obj2.girlfriend=['xiaoming'];控制台日志(obj1);控制台日志(obj2);运行结果:Array.prototype.concat()concat()是数组的内置方法,用户合并两个或多个数组,该方法不会改变已有的数组,而是返回一个新的数组constarr1=[1,{用户名:'明',},];让arr2=arr1.concat();arr1[0]=2;arr1[1].username='萌';控制台日志(arr1);控制台日志(arr2);运行结果:Array.prototype.slice()slice()也是数组的内置方法,该方法会返回一个新的对象slice()不会改变原数组constarr1=[1,{username:'ming',},];让arr2=arr1.slice();arr2[0]=2;arr2[1].username='meng'console.log(arr1);console.log(arr2);运算结果:objexpansionoperatorexpansionoperator是ES6中提出的新的运算符。可用于复制数组、对象和拼接数组。在这一步中,我们也可以尝试使用constobj2={...obj1}的形式进行浅拷贝//拷贝数组constarr1=[1,2,3];constarr2=[...arr1];//像arr。切片()arr2。推(8);安慰。日志(arr1);//[1,2,3]console.log(arr2);//[1,2,3,8]//复制对象constobj1={name:'ming',arr1:['9','7','6'],obj:{name:'meng',arr2:['7','8','9'],},};constobj2={...obj1};//类似于arr.slice()obj2.name='ming2';obj2.arr1=['null'];obj2.obj.name='meng2';obj2.obj.arr2=['null'];console.log(obj1);console.log(obj2);运行结果:深拷贝手动递归函数deepClone(sourceObj,targetObj){让cloneObj=targetObj||{}if(!sourceObj||typeofsourceObj!=="object"||sourceObj.length===undefined){returnsourceObj}if(sourceObjinstanceofArray){cloneObj=sourceObj.concat()}else{for(letiinsourceObj){if(typeofsourceObj[i]==='object'){cloneObj[i]=deepClone(sourceObj[i],{})}else{cloneObj[i]=sourceObj[i]}}}returncloneObj}letsourceObj={a:1,b:{a:1},c:{a:1,b:{a:1}},d:function(){console.log('helloworld')},e:[1,2,3]}lettargetObj=deepClone(sourceObj,{})targetObj.c.b.a=9console.log(sourceObj)console.log(targetObj)results:Json.parse(Json.Stringify())JSON.stringify():将js对象序列化为JSON字符串JSON.parse():将JSON字符串反序列化为js对象constarr9=[1,{用户名:'明',},];让arr10=JSON.parse(JSON.stringify(arr9));arr10[0]=2;arr10[1].username='萌';控制台日志(arr9);控制台日志(arr10);运算结果:letobj={name:'ming',age:20,friend:{name:'ming1',age:19}};让我们pyObj=JSON.parse(JSON.stringify(obj));obj.name='萌';obj.friend.name='meng1';控制台日志(对象);控制台日志(copyObj);运行结果:函数库LodashLodash是一个JavaScript函数库/工具库,里面有很好用的封装函数var_=require('lodash');constobj1=[1,'Hello!',{name:'ming1'},[{name:'meng1',}],]constobj2=_.cloneDeep(obj1);obj2[0]=2;obj2[1]='嗨!';obj2[2].name='ming2'obj2[3][0].name='meng2';console.log(obj1);console.log(obj2);运行结果:最后,如果本文对您有帮助,请为本文点个赞??????欢迎大家加入,一起学习前端,一起进步!
