深拷贝与浅拷贝

    xiaoxiao2022-07-08  222

    深拷贝与浅拷贝

    当复制引用类型的值时,其实就是把变量的值复制一份放在新的变量空间中,但复制的并不是变量本身,而是指向对象的指针,所以在复制引用类型时,改变其中一个会影响另外一个。 深拷贝与浅拷贝其实就是为了解决引用类型的复制操作会使得两个对象共用一个引用的问题 本文围绕对象obj的复制、深拷贝、浅拷贝的问题展开讨论

    var obj={ name:"li", age:19, pre:{ one:"IT", two:"teacher" } }

    如果只是简单的采用var newobj=obj进行对象的复制操作,此时如果修改newobj中的属性,就会使得旧对象obj的相应属性也被修改(如果做如下修改:newobj.age=25),得到的结果将会是:

    浅拷贝

    当要复制的对象的所有属性都不是引用类型时就可以利用浅拷贝实现 浅拷贝的实现方法如下: (1) 遍历,返回新对象

    function shallowCopy(obj){ var newobj={}; if(typeof obj!="object"){ return obj; }else{ for(var k in obj){ if(obj.hasOwnProperty(k)){ newobj[k]=obj[k]; } } return newobj; }

    通过对obj浅复制,此时,如果我们修改newobj.age=20后,同时观察newobj与obj两个对象,我们发现,此时对newobj中age属性的修改并没有影响到obj中的age属性。 但是,当我们对newobj对象中pre的one属性进行修改时:var newobj.pre.one=”student”,此时观察newobj对象与obj对象,我们发现,由于pre属性是一个子对象,此时对属性pre中的one属性进行修改时,会对obj对象中的子对象有影响。 其实,浅拷贝复制的是所有引用类型的指针,而不是具体的值,所以浅拷贝可以解决常见的现象,但是如果对象中还有子对象,则用浅拷贝不够彻底。

    深拷贝

    深拷贝可以彻底的拷贝一个对象 深拷贝的实现方法如下: (1) 递归(如果对象的属性是一个子对象,则进行递归遍历复制,直到遍历完所有的属性)

    //递归实现深拷贝 function deepCopy(obj){ if(typeof obj!=="object"){ return obj; } if(obj instanceof Array){ var newobj=[]; }else{ var newobj={}; } for(var k in obj){ if(typeof obj[k]!=="object"){ newobj[k]=obj[k]; }else{ newobj[k]=deepCopy(obj[k]) } } return newobj; }

    (2) JSON的正反序列化(先将一个对象序列化为JSON字符串,再将JSON字符串解析为对象) 我们采用递归的方式实现对象obj的深拷贝,观察如下的结果: 修改newobj.age=20,同时观察newobj与obj两个对象,我们发现,此时对newobj中age属性的修改并没有影响到obj中的age属性。 修改newobj对象中pre的one:var newobj.pre.one=”worker”,此时观察newobj对象与obj对象,我们发现,此时对newobj中pre的one属性的修改并没有影响到obj中的属性。

    最新回复(0)