js深度拷贝
1.浅拷贝
拷贝就是把父对像的属性,全部拷贝给子对象。
下面这个函数,就是在做拷贝:
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
var
Chinese = {
nation: "中国"
}
var
Doctor = {
career: "医生"
}
function
extendCopy(p) {
var
c = {};
for
( var
i in
p) {
c[i]
= p[i];
}
c.uber
= p;
return
c;
}
|
使用的时候,这样写:
?1 2 3 |
var
Doctor = extendCopy(Chinese);
Doctor.career
= "医生" ;
alert(Doctor.nation);
//
中国
|
但是,这样的拷贝有一个问题。那就是,如果父对象的属性等于数组或另一个对象,那么实际上,子对象获得的只是一个内存地址,而不是真正拷贝,因此存在父对象被篡改的可能。
请看,现在给Chinese添加一个”出生地”属性,它的值是一个数组。
Chinese.birthPlaces = ["北京","上海","香港"];
通过extendCopy()函数,Doctor继承了Chinese。
var Doctor = extendCopy(Chinese);
然后,我们为Doctor的”出生地”添加一个城市:
Doctor.birthPlaces.push("厦门");
看一下输入结果
alert(Doctor.birthPlaces); //北京, 上海, 香港, 厦门
alert(Chinese.birthPlaces); //北京, 上海, 香港, 厦门
结果是两个的出生地都被改了。
所以,extendCopy() 只是拷贝了基本类型的数据,我们把这种拷贝叫做“浅拷贝”。
2.深拷贝
因为浅深拷有如此弊端所以我们接下来看一下深拷贝
所谓”深拷贝”,就是能够实现真正意义上的数组和对象的拷贝。它的实现并不难,只要递归调用”浅拷贝”就行了。
?1 2 3 4 5 6 7 8 9 10 11 12 |
function
deepCopy(p, c) {
var
c = c || {};
for
( var
i in
p) {
if
( typeof
p[i] === "object" )
{
c[i]
= (p[i].constructor === Array) ? [] : {};
deepCopy(p[i],
c[i]);
}
else
{
c[i]
= p[i];
}
}
return
c;
}
|
看一下使用方法:
var Doctor = deepCopy(Chinese);
现在,给父对象加一个属性,值为数组。然后,在子对象上修改这个属性:
?1 2 3 4 5 |
Chinese.birthPlaces
= [ "北京" , "上海" , "香港" ];
|