深入了解JavaScript中的浅拷贝和深拷贝

深入了解JavaScript中的浅拷贝和深拷贝

ID:83375641

大小:814.55 KB

页数:9页

时间:2023-07-15

上传者:无敌小子
深入了解JavaScript中的浅拷贝和深拷贝_第1页
深入了解JavaScript中的浅拷贝和深拷贝_第2页
深入了解JavaScript中的浅拷贝和深拷贝_第3页
深入了解JavaScript中的浅拷贝和深拷贝_第4页
深入了解JavaScript中的浅拷贝和深拷贝_第5页
深入了解JavaScript中的浅拷贝和深拷贝_第6页
深入了解JavaScript中的浅拷贝和深拷贝_第7页
深入了解JavaScript中的浅拷贝和深拷贝_第8页
深入了解JavaScript中的浅拷贝和深拷贝_第9页
资源描述:

《深入了解JavaScript中的浅拷贝和深拷贝》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库

深入了解JavaScript中的浅拷贝和深拷贝这篇文章介绍的内容是关于深入了解JavaScv-ipt中的浅拷贝和深拷贝,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下在JS中有一些基本类型像是NuW\bev、StviV\.9、BooleaV\.,而对象就是像这样的东西{V\.aW\e:'Lav-v-y勹skill:1NodeJs1},对象跟基本类型最大的不同就在千他们的传值方式。基本类型是按值传递,像是这样:在修改a时并不会改到bvara=25;varb=a;b=18;lconsole.log(a);//25console.log(b);//18但对象就不同,对象传的是按引用传值:~varobj1={a:10,b:2O,c:30};varobj2=objl;lobj2.b=100;lconsole.log(objl);//{a:10,b:100,c:30}<--b被改到了console.log(obj2);-;;{a:10,b:100,c:30J复制一份obj:i叫做obj2,然后把obj2.b改成1-00,但却不小心改到obj:i.b,因为他们根本是同一个对象,这就是所谓的浅拷贝。要避免这样的错误发生就要写成这样:varobj1={a:10,b:20,c:30l;2varobj2={a:objl.a,b:objl.b,c:objl.c};

1obj2.b=100;console.log(objl);//{a:10,b:20,c:30}<--b没被改到console.log(obj2);II{a:10,b:100,c:30这样就是深拷贝,不会改到原本的obj1。浅拷贝(Sha((owCopy)VS深拷贝(DeepCopy)ShallowCopyDeepCopy浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。浅拷贝的实现方式也就是简单地复制而已工、简单地复制语句functionsimpleClone(initalObj)varobj={};for(variininitalObjobj[i]=initalObj[i];

2re七1,1mobj;varobj=a:"hello",Lb:{11a:"world",Lb:21l:},llc:["Bob","Tom","Jenny"J,1·d:function(){Halert("helloworld");18}varcloneObj=simpleClone(obj);console.log(cloneObj.b);console.log(cloneObj.c);console.log(cloneObj.d);cloneObj.b.a="changed";cloneObj.c=(1,2,3];cloneObj.d=func七ion(){alert("changed");};console.log(obj.b);,console.log(obj.c);沪console.log(obj.d);

3是0切ect.assig八()进行的是浅拷贝,拷贝的是对象的属性的引用,而不是对象本身。JObject.assign(target,...sources)参数:tav-9et:目标对象。souv-ces:任意多个源对象。返回值:目标对象会被返回。lva工obj={a:{a:"hello",b:21)};varinitalObj=Object.assign({},obj);initalObj.a.a="changed";console.log(obj.a.a);//"changed"兼容性:Eea过reChroMeFrefox\Gee:o)lmerne:ExotorerOperaSafariEdgeBasicsuppon乙53.!(34)未实现329~占文网需要注意的是:lObject.assign()可以处理一层的深度拷贝,如下:va工objl={a:10,b:20,c:30};varobj2=Object.assign({},objl);obj2.b=100;console.log(objl);II{a:10,b:20,c:30l<--没被改到console.log(obj2);II{a:10,b:100,c:30J

4深拷贝的实现方式要完全复制又不能修改到原对象,这时候就要用DeepCopy,这里会介绍几种DeepCopy的方式。1、手动复制把一个对象的屈性复制给另一个对象的属性varobj1={a:10,b:20,c:30};varobj2={a:objl.a,b:objl.b,c:objl.c};0切2.b=100;console.log(objl);//{a:10,b:20,c:30}<--没玻改到console.log(obj2);//{a:10,b:100,c:30}但这样很麻烦,要一个一个自己复制;而且这样的本质也不能算是DeepCopy,因为对象里面也可能回事对象,如像下面这个状况:lvarobjl={body:{a:10}};~varobj2={body:objl.body};obj2.body.a=20;console.log(www.267774.comobjl);IIIbody:{a:20)J<--被改到了console.log(obj2);IIIbody:Ia:20JJconsole.log(objl===obj2);//false_console.log(objl.body===obj2.body);7//true虽然obj1跟obj2是不同对象,但他们会共享同一个obj1-.body,所以修改obj2.bod胪.a时也会修改到旧的。2、对象只有一层的话可以使用上面的:Object.assi9八()函数

5Object.ass你({}Jobj功的意思是先建立一个空对象{},接着把obj:1-中所有的属性复制过去,所以obj2会长得跟obj:1-一样,这时候再修改obj2.b也不会影响obj工因为Object.assi9八跟我们手动复制的效果相同,所以一样只能处理深度只有一层的对象,没办法做到真正的DeepCop~。不过如果要复制的对象只有一层的话可以考虑使用它。歹、转成JSON再转回来用JSON.stv-i八9if~把对象转成字符串,再用JSON.pav-se把字符串转成新的对象。lvarobjl={body:{a:10}};-Va工obj2=JSON.parse(JSON.stringify(objl));obj2.body.a=20;console.log(objl);II{body:{a:10)}<--没被改到console.log(obj2);II{body:{a:20ll0console.log(objl===obj2);//false1console.log(objl.body===obj2.body);//false这样做是真正的DeepCopy,这种方法简单易用。但是这种方法也有不少坏处,譬如它会抛弃对象的co八stvuctor。也就是深拷贝之后,不管这个对象原来的构造函数是什么,在深拷贝之后都会变成Object。

6这种方法能正确处理的对象只有NuW\be亿Stvin9.,Boolean丿Avva!:J丿扁平对象,即那些能够被json直接表示的数据结构。Re9Exp对象是无法通过这种方式深拷贝。也就是说,只有可以转成JSON格式的对象才可以这样用,像function没办法转成JSON。~varobjl={fun:function(){console.log(l23)}};varobj2=JSON.parse(JSON.stringify(objl));'console.log(typeofobjl.fun);,1//'function'console.log(typeofobj2.fun);//'undefined'<--没复制要复制的fu八ctio八会直接消失,所以这个方法只能用在单纯只有数据的对象。4、递归拷贝lfunctiondeepClone(initalObj,finalObj){Lvarobj=finalObjII{};for(v扛iininitalObj){4i.f(typeofinitalObj[i]==='object'){obj[i]=(initalObj[i].constructor===Array)?[){};arguments.callee(].n].talObj(].],obj(].]);el.Se{obj[].]=in].talObj[].];111乞returnobj;1..:1varstr={);varobj={a:{a:"hello",b:21)};1,deepClone(obj,str);console.log(str.a);上述代码确实可以实现深拷贝。但是当遇到两个互相引用的对象,会出现死循环的情况。

7为了避免相互引用的对象导致死循环的情况,则应该在遍历的时候判断是否相互引用对象,如果是则退出循环。改进版代码如下:1functiondeepClone(initalObj,finalObj){va亡obj=finalObjII{};for(variininitalObj){va工prop=initalObj[工];//避免相互引用对象导致死循环,如1肛talObj.a=initalO切的情况if(prop===obj)con七inue;工f(typeofprop==='object'){1obj[i]=(prop.construe七or===Array)?[]{};larguments.callee(prop,obj[i]);e.lse{3obj[i]=prop;1tr1式urnobj;~}vars七r={};varobj=Ia:{a:"hello",b:21}};l~deepClone(obj,str);console.log(str.a);S、使用Object.createO方法直接使用var八ewObj=Object.cv-eate(oldObj),可以达到深拷贝的效果。lfunctiondeepClone(initalObj,finalObj){Lvarobj=finalObjII{};for(variinini七alObj){Avarprop=initalObj[i];//避免相且引用对象导致死循环,如initalObj.a=initalObj的悄况if(prop===obj){continue;Qif(typeofprop==='object'){

8obj[i](prop.constructor===Array)?[]:Object.create(prop);}else{obj[i]=prop;45}returnobj;仓jquer!:Jjquevy有提供一个$.exte八d可以用来做DeepCopy。var$=require('jquery');varobjla:1,b:{f:{g:1}},4c:(1,2,3]};varobj2=$.extend(true,{www.jiekeqipai.net},objl);console.log(objl.b.f===obj2.b.f);//false7、(odash另外一个很热门的函数库lodast-t,也有提供_.clo八eDeep用来做DeepCopy。1var_=require('lodash');va工objl={a:1,b:{f:{g:1}},4c:(1,2,3]};varobj2=_.cloneDeep(objl);console.log(objl.b.f===obj2.b.f);//false这个性能还不错,使用起来也很简单。

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
最近更新
更多
大家都在看
近期热门
关闭