<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">首先,什么是深度克隆?深度克隆就是说,有对象a,现在利用a克隆对象b,b与a具有相同的方法和属性,而且两者不能相互影响。</span>
我们可能会想到直接赋值,
var a = 3;
var b = a;
a = 20;
console.log(b); // 3
var a = 'hello';
var b = a;
a = 'world';
console.log(b); // hello
似乎没问题,我们再看
//函数
var a = function() {console.log(1);};
a.tmp = 10;
var b = a;
a.tmp = 20;
console.log(b.tmp); // 20
//数组
var a = [0, 1, 2, 3];
var b = a;
a.push(4);
console.log(b); // [0, 1, 2, 3, 4]
显然,两个对象会相互影响。出现这种情况的原因是因为,js变量有两种类型,原始类型:number、string和boolean,合成类型:array、object和function。
基本类型赋值会重新分配地址,但是合成类型是指向同一个地址,所以会相互影响。
解决方法如下:
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
<span style="white-space:pre"> </span>//这一步达到了重新分配地址空间的效果
str = JSON.stringify(obj), //系列化对象
newobj = JSON.parse(str); //还原
} else {
<span style="white-space:pre"> </span>//for...in循环会把原型链上的属性也便利出来,for循环则只便利非原型链上的属性
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};
//测试
var obj = {a: 0, b: 1, c: 2};
var arr = [0, 1, 2];
//执行深度克隆
var newobj = cloneObj(obj);
var newarr = cloneObj(arr);
//对克隆后的新对象进行成员删除
delete newobj.a;
newarr.splice(0,1);
console.log(obj, arr, newobj, newarr);
//结果: {a: 0, b: 1, c: 2}, [0, 1, 2], {b: 1, c: 2}, [1, 2];
http://www.cnblogs.com/zichi/p/4568150.html
http://sentsin.com/web/21.html