深拷贝
对于前端开发者来说,我们几乎无时无刻都在接触对象。说起对象就不得不说起引用数据类型。所谓引用数据类型就是在js中,对象是放在堆内存中,栈中只是存放着对象对在堆内存中的存放地址。因此,当我们对对象进行赋值的时候,只要不改变对象的引用地址,所有的对象都会跟着改变。这当然我们想要的效果,有时候我们需要保存一份初始数据,如果初始数据跟着赋值对象一起改变肯定就不行了。因此,也就出现了深拷贝和浅拷贝一说,所谓深拷贝就是赋值对象不会随着被赋值对象改变而改变,反之就是浅拷贝。实现深拷贝很简单,我们为每一个对象都重新开辟一块新的内存,自然内存地址也就跟赋值对象不一样,也就不会影响到初始赋值数据。
下面我们先来看一下浅拷贝的几个例子:
大家可以看到,使用Object.assign来进行对象复制的时候,它只能深拷贝第一层对象属性,第二层或者更深的层次无法进行深拷贝,所以Object.assign最好只用于单层对象的拷贝。
实现深拷贝
要想不出现Object.assign这种只能进行一层拷贝的局限性,我们来实现一个深拷贝函数对每一层都进行深拷贝。
function deepClone(obj){
if(typeof obj ==="object"&&obj ){
var data=Array.isArray(obj)?[]:{};
for(var prop in obj){
data[prop]=deepClone(obj[prop])
}
return data
}else {
return obj
}
}
大家可以自己尝试一下,无论是多少层对象,均能够完美copy,并且不会影响初始赋值对象。实现深拷贝的需要注意一点的就是,在递归赋值的过程中,要注意数组对象和对象的赋值。