浅拷贝
要想理解深拷贝,我们先来看一下浅拷贝,废话不多说,直接上代码
var obj = { a:1, arr: [2,3] };
var shallowObj = shallowCopy(obj);
function shallowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
看这个例子,我们把obj对象直接拷贝给了shallowObj,不过这样有什么问题呢,比如我们再给shallowObj增加一个属性name:
shallowObj.arr.push('qing');
console.log(shallowObj);
console.log(obj)
可以看到obj也随着发生了改变
因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制,而 JavaScript 存储对象都是存地址的,所以浅复制会导致obj.arr 和 shallowObj.arr 指向同一块内存地址。
大概的示意图如下
深拷贝
递归实现
var people = {
name:'xxx',
friends:['people1','people2','peopple3'],
info:{
phone:'133xxxxxxxx',
age:'18',
sex:'man'
}
}
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 person = deepCopy(people);
JSON实现
var result = JSON.parse(JSON.stringify(people))
我们给两种方法得到的新对象增加方法
person.friends.push('qing');
result.friends.push('Leon');
可以看到结果如下
所以原对象不会随着深拷贝过的对象而改变,深拷贝不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上