/*****************************************************************************************/
原生js实现深拷贝
function clone(target){
if(typeof target === 'object'){
let obj = Array.isArray(target) ? [] : {}
for(const key in target ){
obj[key] = clone(target[key])
}
return obj;
}else{
return target;
}
}
例子:
var obj1 = {
name:'abc',
age:10,
children:{
name:'abc-child',
age:2
},
address:[1,2,3,4,56,323]
}
var obj2 = clone(obj1) // 得出obj2对象
/*****************************************************************************************/
以上拷贝能解决大部分深拷贝问题,除了还有引用的对象;
例子:
obj1.obj = obj1 //
var obj3 = clone(obj1) //----会报错
报错信息:
Uncaught RangeError: Maximum call stack size exceeded
at new Map (<anonymous>)
at clone (<anonymous>:1:29)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
at clone (<anonymous>:9:24)
原因:obj1的深拷贝引出了无限循环,因为obj1.obj引用了它本身;
解决办法:
1, obj1.obj = clone(obj1)
2,修改clone方法如下:
function clone(target,map=new Map()){
if(typeof target === 'object'){
let obj = Array.isArray(target) ? [] : {}
if(map.get(target)){
return target;
}
map.set(target,obj);
for(const key in target ){
obj[key] = clone(target[key])
}
return obj;
}else{
return target;
}
}
/*优化版*/
function clone(target,map=new WeakMap()){
if(typeof target === 'object'){
let obj = Array.isArray(target) ? [] : {}
if(map.get(target)){
return target;
}
map.set(target,obj);
for(const key in target ){
obj[key] = clone(target[key])
}
return obj;
}else{
return target;
}
}
obj1.obj = obj var obj3 = clone(obj1,map)