手机版

详细解释JavaScript对象的深度和浅度复制

时间:2021-09-05 来源:互联网 编辑:宝哥软件园 浏览:

从层次的角度来看,对象复制可以简单地分为浅层复制和深层复制。顾名思义,浅层复制是指只复制一层对象的属性,而不复制对象中的属性,但是对象的深层复制会复制层中嵌套对象的属性。

复制对象时,我们不仅要复制对象的属性,还要考虑对象的构造函数属性是否保留,各种数据类型(String、Number、boolean、data、regexp、array、fun、object都是JavaScript中常见的数据类型)是否可以正确复制。在项目中,我们可以根据实际情况决定需要实现什么程度的复制。

本文是我复制对象经验的总结,从浅复制到深复制,从复制简单属性到复制复杂属性,如Function和RegExp。如果有任何不当的说法,请指出来,我们很感激。

主体

浅拷贝

浅层复制只依次复制对象的每个属性,而不递归复制这些属性。下面是一个简单的浅层复制实现。

//对象浅层复制函数卷影复制(obj){ if(obj的类型!=='object ')返回objfor(var prop in obj){ if(obj . hasown property(prop)){ new obj[prop]=obj[prop];} }返回newObj}经过仔细观察,不难发现上述方法的缺陷:

1.无法正确实现阵列的浅层复制

2.复制操作丢失了对象的构造函数属性

好了,我们现在已经发现了问题,只需要有针对性的解决,一个比较完善的浅复制对象的方法就诞生了!

//对象浅层复制函数卷影复制(obj){ if(obj的类型!=='object ')返回;var newObj//保留对象的构造函数属性if (obj。构造函数===array){ new obj=[];} else { newObj={ }new obj . constructor=obj . constructor;} for(var prop in obj){ if(obj . hasown property(prop)){ NewObj[prop]=obj[prop];} }返回newObj}在浏览器中测试:

var arr1=[0,1,2];console . log(arr 1);console . log(ShadowCopy(arr 1));var arr2=[0,1,2,[3,4,5]],arr 2 copy=shadow copy(arr 2);console . log(arr 2);console . log(arr 2 copy);arr 2 copy[3][0]=6;console . log(arr 2[3][0]);//6

很好!正确复制数组并保留构造函数是可能的,但必须发现轻度复制对象的arr2Copy[3]和arr2[3]指向一个对象,并同时更改其中一个和另一个。我们想实现的是复制,但这不是复制!这是浅层复制的缺点。接下来,让我们看看深度复制如何解决这个问题。

深度复制

深度复制需要逐层递归,复制对象的所有属性,包括对象属性的属性.(halo ~)如果只需要简单复制对象的属性,不考虑其构造函数,也不考虑函数、正则性、数据等特殊数据类型,那么有一个深度复制的小技巧,可以用两行代码:

函数deepCopy(obj){ if(typeof obj!==' object '){ return;} var str=JSON . stringify(obj);返回JSON.parse(字符串);}在大多数情况下,上述方法可以满足要求,但有时,我们需要考虑函数、正则性等特殊数据类型,或者在当前环境不支持JSON时,上述方法不适用。此时,我们可以通过递归实现对象的深度复制,如下所示:

函数deepCopy(obj){ if(typeof obj!==' object '){ return;} var newObj//保留对象的构造函数属性if (obj。构造函数===array){ new obj=[];} else { newObj={ }new obj . constructor=obj . constructor;} for(obj中的var prop){ if(type of obj[prop]===' object '){ if(obj[prop])。构造函数===RegExp ||obj[prop]。构造函数===Date){ NewObj[prop]=Obj[prop];} else {//递归new obj[prop]=deep copy(obj[prop]);} } else { NewObj[prop]=obj[prop];} }返回newObj}首先用上面的例子进行测试:

太好了。您可以正确复制多维数组,然后看看是否可以复制函数和正则性:

函数Person(name){ this . name=name;this.age=年龄;this.search=new RegExp(名称);这个。say=function () {console。日志(这个。名字‘今年’这个.年龄‘老了’);}}var p1=new Person('Claiyre ',20),p2=deep copy(P1);console . log(P1);console . log(p2);p2 .年龄=22岁;P1 . say();p2 . say();

圆满完成!

稍微排序后,我们可以得到一个更通用的js对象复制函数:

函数DeepCopy(obj){ var NewObj=obj . constructor===Array?[]:{};new obj . constructor=obj . constructor;if(typeof obj!==' object '){ return;} else if(窗口。JSON){ //如果需要考虑特殊的数据类型,比如正则、函数等。则需要去掉这个else if,这样new obj=JSON . parse(JSON . stringfy(obj));} else { for(var prop in obj){ if(obj[prop])。构造函数===RegExp ||obj[prop]。构造函数===Date){ NewObj[prop]=Obj[prop];} else if(obj[prop]==' object '的类型){//递归新obj[prop]=deep copy(obj[prop]);} else { NewObj[prop]=obj[prop];} } }返回newObj}结论

以对象为核心的面向对象编程语言对学习过程非常有益。

以上是边肖介绍的JavaScript对象的深浅复制,希望对大家有所帮助。如果你有任何问题,请给我留言,边肖会及时回复你。非常感谢您对我们网站的支持!

版权声明:详细解释JavaScript对象的深度和浅度复制是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。