目录
- [递归] new Map() 做为函数内部变量时 栈溢出
- [递归] new Map() 做为函数参数时 解决了循环引用的问题
- 递归赋值过程
一、[递归] new Map() 做为函数内部变量时 栈溢出
//使用Map函数
function deepcopy(obj, map = new Map()){
if(typeof obj !== 'object'){return}
let res = Array.isArray(obj) ? [] :{};
if(map.get(obj)){
return map.get(obj);
}
map.set(obj,res);
//console.log('map', map);
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(typeof obj[key] === 'object'){
res[key] = deepcopy(obj[key]);
}else{
res[key] = obj[key];
}
}
}
return res;
};
var obj={a:1,b:2}
obj.c=obj
var deepcopyObj2 = deepcopy(obj);
//deepcopyObj2.c.c1=666
console.log(obj,deepcopyObj2);
二、[递归] new Map() 做为函数参数时 解决了循环引用的问题
使用 WeakMap() 也一样可以
只修改了注释处的两处
function deepcopy(obj, map = new Map()){ // 把函数内变量转为参数使用
if(typeof obj !== 'object'){return}
let res = Array.isArray(obj) ? [] :{};
if(map.get(obj)){
return map.get(obj);
}
map.set(obj,res);
//console.log('map', map);
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(typeof obj[key] === 'object'){
res[key] = deepcopy(obj[key],map); // 修改了此处,传入map
}else{
res[key] = obj[key];
}
}
}
return res;
};
var obj={a:1,b:2}
obj.c=obj
var deepcopyObj2 = deepcopy(obj);
console.log(obj,deepcopyObj2);
三 递归赋值过程
从里到外,深度优先
function deepcopy(obj, map = new Map()){
if(typeof obj !== 'object'){return}
let res = Array.isArray(obj) ? [] :{};
if(map.get(obj)){
return map.get(obj);
}
map.set(obj,res);
console.log('map:::', map);
for(let key in obj){
if(obj.hasOwnProperty(key)){
if(typeof obj[key] === 'object'){
res[key] = deepcopy(obj[key],map);
}else{
res[key] = obj[key];
}
}
}
console.log(res);
return res;
};
var obj={a:1,b:2,c:{},d:{e:{f:{i:{g:3}}}}}
obj.c=obj
var deepcopyObj2 = deepcopy(obj);
参考
总结
- [递归] new Map() 做为函数内部变量时 栈溢出的原因? 为何做为参数就可以?
- 在JS中有一些已经封装好的如数组方法:
concat(),filter(),slice(),map()等,在修改数组时,不会修改原来的数组,而是返回一个新的数组。但这并不是真正的深拷贝,当数组中嵌套数组对象时仍为浅拷贝,嵌套数组的改变仍会影响原数组的值