相信人很多学习js的过程中都踩了深拷贝和浅拷贝的坑,深拷贝和浅拷贝的区别我就不再赘述了,今天我来写一下我自己实现深拷贝的各种方法。
比较简单的拷贝方式可以借用浏览器的Json对象去实现,先把对象转化为json字符串,在解析回对象实现深拷贝。具体代码就是JSON.parse(JSON.stringify(target));但是这种比较hack的方法总归不是正途,现在我就来贴两种我自己写的深拷贝代码。
function deepClone(currobj){
if(typeof currobj !== 'object'){
return currobj;
}
if(currobj instanceof Array){
var newobj = [];
}else{
var newobj = {}
}
for(var key in currobj){
if(typeof currobj[key] !== 'object'){
newobj[key] = currobj[key];
}else{
newobj[key] = deepClone(currobj[key])
}
}
return newobj
}
第一种自然就是递归,遍历对象的每一个属性然后赋值到新对象了,若是有深层次嵌套的对象,递归执行函数。jq中的深拷贝也是用类似方法实现。
function deepClone(currobj){
if(typeof currobj !== 'object'){
return currobj;
}
if(currobj instanceof Array){
var newobj = [];
}else{
var newobj = {}
}
var currQue = [currobj], newQue = [newobj];
while(currQue.length){
var obj1 = currQue.shift(),obj2 = newQue.shift();
for(var key in obj1){
if(typeof obj1[key] !== 'object'){
obj2[key] = obj1[key];
}else{
if(obj1[key] instanceof Array ){
obj2[key] = [];
}else{
obj2[key] = {}
};
currQue.push(obj1[key]);
newQue.push(obj2[key]);
}
}
}
return newobj;
};
上一种递归的方式容易引起内存溢出,特别是对一个比较复杂,层级很深的对象进行深拷贝。所以第二种方法是用循环去拷贝次级的对象,用两个队列去保存需要拷贝的对象和拷贝目标,利用浅拷贝的原理实现了深拷贝。
但是有时候对象会存在子属性指向自身的问题,形成对象环,我这暂时还没有考虑到。
突然看到自己这篇文章,其实对象环的问题只需要别将旧数组出栈就行了具体代码:
function deepClone(currobj){
if(typeof currobj !== 'object'){
return currobj;
}
if(currobj instanceof Array){
var newobj = [];
}else{
var newobj = {}
}
var currQue = [currobj], newQue = [newobj], i = 0;
while(i <= currQue.length - 1){
var obj1 = currQue[i++],obj2 = newQue.shift();
for(var key in obj1){
if(typeof obj1[key] !== 'object'){
obj2[key] = obj1[key];
}else{
if(currQue.includes(obj1[key])){
obj2[key] = obj1[key];
continue;
}
if(obj1[key] instanceof Array ){
obj2[key] = [];
}else{
obj2[key] = {}
};
currQue.push(obj1[key]);
newQue.push(obj2[key]);
}
}
}
return newobj;
};
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。