克隆
浅度克隆:原始类型为值传递,对象类型为引用传递
深度克隆:所有对象的属性和值均全部复制,即所有新对象的修改不会影响原对象。
函数的克隆通过浅克隆就可以实现,并不影响原函数。因为函数克隆会在内存中单独开辟一片空间,互不影响。
var n=function(){
alert(1);
}
var m=n;
m=function(){
alert(2);
}
Console.log(n());//1
Console.log(m());//2
克隆对象必须用深度克隆。浅度克隆,克隆的是对象的引用,等到修改克隆对象时会修改原对象。
第一种方法:
下面是我从某网上敲下来别人的代码:
function deepclone(parent,child){
child=child||{};
for(var i in parent){
//检查当前对象是否有这个属性
if(parent.hasOwnProperty(i)){
//如果当属性为对象,还要判断其是否为数组
if(typeof parent[i]==="object"){
child[i]=(Object.prototype.toString.call(parent[i]==='[object Array]')?[]:{});
//调用递归
deepclone(parent[i],child[i]);
}else{
child[i]=parent[i];
}
}
}
return child;
}
var dad={
counts:[1,2,3],
reads:{paper:true}
};
var kids=deepclone(dad);
console.log(deepclone(dad,kids));
kids.counts.push(4);
kids.reads.paper=false;
console.log(kids.counts);
console.log(kids.reads.paper);
console.log(dad.counts);
console.log(dad.reads.paper);
运行结果:
利用上面这种方法实现深度克隆需要注意以下几点:
- 先判断当前遍历的属性为对象。
- 由于数组也是特殊的对象,所以还需要判断是不是数组。
- 如果是数组创建一个空[],如果是一个对象创建一个空{},并且赋值给当前子对象的属性,然后调用递归克隆函数。
第二中方法:利用Json.parse()和json.stringify. 利用内置函数处理起来会比较快。
JSON.stringify()将对象转换成json字符串
JSON.parse()将json字符串转换成对象
function deepclone(parent,child){
var i;
var proy;
proy=JSON.stringify(parent);
proy=JSON.parse(proy);
child=child||{};
for(var i in proy){
if(proy.hasOwnProperty(i)){
child[i]=parent[i];
}
}
proy=null;//由于proy是中间对象所以可以回收
return child;
}
var dad={
interst:['football','basketball'],
tall:{
data:true
}
};
var kid=deepclone(dad);
kid.interst.push('pingpang');
kid.tall.data=false;
console.log(kid.interst);
console.log(kid.tall.data);
console.log(dad.interst);
console.log(dad.tall.data);
运行结果: