在js中,对于字符串,布尔值可直接使用赋值运算符就可以实现深拷贝,但对于引用类型,数组,对象,对象数组的拷贝呢,实际只是进行了浅拷贝
下面是一个数组
var arr = ["a","b"];
现在怎么进行arr数组的拷贝呢,直接赋值来的结果
var arrCopy = arr;
arrCopy[1]="c";
arr // ["a","c"]
可以看出拷贝数组arrCopy进行操作时原数组也相应被改变了,这就是js的浅拷贝。所以对引用类型进行简单的赋值运算,只是创建了一份原内容的引用,指向的仍然是同一块内存区域,修改时会改变原来内容,而我们有时候不需要这样的模式,那怎么样进行深拷贝呢
1.数组的深拷贝
方法1 遍历复制
var arr = ["a","b"];
var arrCopy=[];
for(var item in arr)
arrCopy[item] = arr[item];
arrCopy[1]="c";
arr // => ["a","b"]
arrCopy // ["a","c"]
2.对象的深拷贝
var obj = {"a":1,"b":2};
同样进行赋值运算符操作
var objCopy = obj;
objCopy = 3;
obj // {"a":1,"b":3}
objCopy // {"a":1,"b":3}
同样,简单的赋值运算只是一份浅拷贝。
对于对象的深拷贝,没有内置方法可以使用,我们可以自己命名一个函数进行这项操作:
var objDeepCopy = function(source){
var sourceCopy = {};
for(var item in source){
sourceCopy[item]= source[item];
}
return sourceCopy;
}
但是对于复杂结构的对象,这个函数并不适用,例如:
var obj = {"a":
{"a1":["a11","a12"],"a2":1},
"b":2}
还需要修改一下:
var objDeepCopy = function(source){
var sourceCopy = {};
for(var item in source){
sourceCopy[item]= typeof source[item] === 'object'? objDeepCopy(source[item]):source[item];
}
return sourceCopy;
}
var objCopy = objDeepCopy(obj);
objCopy.a.a1[1]="a13";
obj // { "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 }
objCopy // { "a": { "a1": ["a11", "a13"], "a2": 1 }, "b": 2 }
3.对象数组的深拷贝
var obj = [
{ "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 },
["c", { "d": 4, "e": 5 }]
];
var objDeepCopy = function (source) {
var sourceCopy = source instanceof Array ? [] : {};
for (var item in source) {
sourceCopy[item] = typeof source[item] === 'object' ? objDeepCopy(source[item]) : source[item];
}
return sourceCopy;
}
var objCopy = objDeepCopy(obj);
objCopy[0].a.a1[1] = "a13";
objCopy[1][1].e = "6";
obj // => [{ "a": { "a1": ["a11", "a12"], "a2": 1 }, "b": 2 }, ["c", { "d": 4, "e": 5 }]]
objCopy // => [{ "a": { "a1": ["a11", "a13"], "a2": 1 }, "b": 2 }, ["c", { "d": 4, "e": 6 }]]