浅拷贝与深拷贝
首先深拷贝和浅拷贝只针对像 Object, Array 这样的复杂对象的。简单来说,浅拷贝只拷贝一层对象的属性,而深拷贝则递归拷贝了所有层级。
浅拷贝
在使用JavaScript对数组进行操作的时候,我们经常需要将数组进行备份,事实证明如果只是简单的将它赋予其他变量,那么我们只要更改其中的任何一个,然后其他的也会跟着改变。
var arr = ["One","Two","Three"];
var arrto = arr;
arrto[1] = "test";
document.writeln("数组的原始值:" + arr + "<br />");
//Export:数组的原始值:One,test,Three
document.writeln("数组的新值:" + arrto + "<br />");
//Export:数组的新值:One,test,Three
像上面的这种直接赋值的方式就是浅拷贝,很多时候,这样并不是我们想要得到的结果。因为浅拷贝只会将对象的各个属性进行依次拷贝,并不会进行递归拷贝,而 JavaScript 存储对象都是存地址的,所以浅拷贝会导致 arr 和 arrto 指向同一块内存地址。
深拷贝
而深拷贝则不同,它不仅将原对象的各个属性逐个拷贝出去,而且将原对象各个属性所包含的对象也依次采用深拷贝的方法递归拷贝到新对象上。即深拷贝会产生新的地址,修改一个对象的属性,不会改变另一个对象的属性。
深拷贝的实现方法
数组
1. js的slice函数
arrayObj.slice(start, [end]);
如var newarr = arr.slice(0);
2.js的concat方法
arrayObject.concat(arrayX,arrayX,......,arrayX);
如var newarr = arr.slice(0);
对象
1.通过JSON解析解决
JSON.stringify:将对象转化为字符串;
JSON.parse :将字符串转化为对象;
如var newobj= JSON.parse(JSON.stringify(obj));
2.遍历对象属性
var deepCopy= function(source) {
var result={};
for (var key in source) {
result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
}
return result;
}
复合写法
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};