为什么会有深拷贝
拷贝一词最早是在学习C++时听到的。在JavaScript中有三种引用值:Array、Object、Function。
引用值在赋值时传递的是地址。若不考虑这一点,单纯的直接“=”,就是我们所说的浅拷贝。拷贝过后,对引用类型数据的修改会影响到拷贝的对象和被拷贝的对象。深拷贝就是在拷贝过程中若遇到了引用值就new 一块新空间来存放引用类型中的普通数据。
递归来实现深拷贝
现在想来,当初学习C++时只是理解了什么是深浅拷贝,如何实现缺没有实践。遗憾遗憾
原理很简单:
遍历要拷贝的目标对象:对于普通属性之间赋值。对于数组或者对象,则新建一个数组或对象,再遍历该数组或对象重复上述步骤即可。
<script type="text/javascript">
function deepClone(origin, target){
var target = target || {}; //当没有传入target对象时,生成一个空对象
for(var prop in origin){
if(origin.hasOwnProperty(prop)){ //拷贝自己的属性
if(origin[prop] !== "null" && typeof(origin[prop]) == "object"){ //typeof(null) 返回值为“object” .咋也不知道
target[prop] = Object.prototype.toString.call(origin[prop]) == "[object Array]" ? [] : {};
deepClone(origin[prop], target[prop]); //递归直到不含引用值为止
}else{
target[prop] = origin[prop];
}
}
}
return target;
}
var origin = {
a : "123",
b : [1,2,3],
c : {
d : 1,
f : 2
}
}
var copy = deepClone(origin);
copy.b.push(4,5,6);
copy.c.g = 3;
console.log(copy);
console.log(origin);
</script>
可以看到对copy的修改不会影响到origin