概念介绍深拷贝:在堆内存中重新开辟一块存储空间,完全克隆一个一模一样的对象;浅拷贝:不在堆内存中重新开辟空间,只复制内存中的栈引用地址。本质上,两个对象(数组)仍然指向同一个存储空间。第一种:递归方式(推荐,最安全,项目中最常用)使用递归方式进行对象(数组)的深拷贝,并给出封装的深拷贝函数:上面函数的使用方法://函数拷贝constcopyObj=(obj={})=>{//变量为空先让newobj=null;//判断是否继续递归if(typeof(obj)=='object'&&obj!==null){newobj=objinstanceofArray?[]:{};//进行下一级递归克隆for(variinobj){newobj[i]=copyObj(obj[i])}//如果对象没有直接赋值}elsenewobj=obj;返回新对象;}上面函数的用法://模拟对象letobj={numberParams:1,functionParams:()=>{console.log('昨天资金都是绿色的,只有我的眼睛是红色的');},objParams:{a:1,b:2}}constnewObj=copyObj(obj);//这样就完成了一个对象的递归复制obj.numberParams=100;//改变第一个对象的引用console.log(newObj.numberParams);//输出还是1,不会跟着obj改第二个:JSON.stringify();(这个不推荐使用,有坑)这个方法有坑,详细解释可以参考我的另一篇文章《PitchesofdeepcopyingusingJSON.stringify》。下面是一个代码示例:letobj={a:1,b:“基金亏的太多了,总有一天,你站在屋顶,我躺在轨道上,下辈子我们有说有笑。”}//先转成json格式字符,再转回让newObj=JSON.parse(JSON.stringify(obj));obj.a=50;console.log(newObj.a);//输出1普通对象也可以深拷贝,但是!!!当object内容项为number,string.boolean时,没有问题。但是,如果对象内容项是undefined,null,Date,RegExp,function,error。使用JSON.stringify()复制会出问题。第三种方法:是否推荐使用第三方库lodash中的cloneDeep()方法看情况。如果我们的项目中只需要一个深拷贝功能,这种情况下不值得为一个功能引入整个第三方库。为了项目的性能,还是写一个递归函数比较好。lodash.cloneDeep()代码示例:从'lodash'导入lodash;letobj={a:{c:2,d:[1,3,5],e:'abaaba'},b:4}constnewObj=lodash.cloneDeep(obj);obj.b=20;console.log(newObj.b);//输出4;不会变其实cloneDeep()方法底层是一个递归方法。它只是在外层的另一层封装。因此,如果原项目中没有使用到lodash库,则该功能无需引入。文首有深拷贝的功能,推荐。每个人都可以拿起它。第四种:JQuery的用于深拷贝的extend()方法(推荐在JQ中使用)这种方法只适用于JQuery构建的项目。JQuery本身自带的extend()方法可以进行深拷贝,不需要写递归,也不需要引入第三方库,没有坑。JQuery项目中的用法:letobj={a:{c:2,d:[1,3,5],e:'Abaaaba'},b:4}letnewObj=$.extend(true,{},obj1);//复制完整obj.b=20;console.log(newObj.b);//Output4Summary:深拷贝的方法:递归函数(推荐,项目中用的更多,更小,更安全)JSON.stringify()和JSON.parse();(不推荐,如果遇到Function、Date等类型的变量,很容易出现一些意想不到的问题)第三方库lodash的cloneDeep()方法(视情况而定,如果有第三方库项目中调用lodash,可以使用,否则建议使用递归函数。否则成本太高。)JQuery的extend()函数(推荐在JQuery项目中使用,其他项目还是建议使用递归函数)
