区别
深拷贝是递归复制了所有的层级 --------- 在堆中重新分配内存,并且把源对象的所有属性都进行新建拷贝,以保证深拷贝的对象的引用图不包含任何原有对象或对象图上的任何对象,拷贝后的对象与原来的对象是完全隔离,互不影响。
浅拷贝是复制一层对象的属性 -------- 浅拷贝是拷贝引用,拷贝后的引用都是指向同一个对象的实例,彼此之间的操作会影响互相操作
浅拷贝
var obj = {a: 1, arr: [2,3]};
var shadowObj = shadowCopy(obj);
function shadowCopy(src) {
var dst = {};
for (var prop in src) {
if (src.hasOwnProperty(prop)) {
dst[prop] = src[prop];
}
}
return dst;
}
浅拷贝只拷贝一层,所以相当于改变原来对象中arr中的某个子元素的时候,拷贝的对象shadowObj中的arr对应的该元素值也会跟着改变,在js中存储对象都是存地址的,浅复制中那些子对象都是指向的是同一块内存地址
源对象拷贝实例,其属性对象拷贝引用
对源对象直接操作,不影响另外一个对象,但是对其属性操作时候,会改变另外一个对象的属性值。
实际上这就是浅拷贝的影响:
Array.prototype.slice()
Array.prototype.concat()
jQuery中的$.extend({}, obj)
深拷贝的实现方式
1、递归的方式
function deepCopy (sourceObj) {
if (!sourceObj && typeof sourceObj !=='object') {
throw new Error('error arguments', 'shallowClone');
}
var targetObj = sourceObj.constructor === Array ? [] : {};
for (var keys in sourceObj) {
if (sourceObj.hasOwnProperty(keys)) {
// 先判断子元素的类型是对象还是基本类型,基本类型直接赋值,对象的话需要再次递归
if (sourceObj[keys] && typeof sourceObj[keys] === 'object') {
targetObj[keys] = source[keys].constructor === Array ? [] : {};
targetObj[keys] = deepCopy(source[keys]);
} else {
targetObj[keys] = source[keys];
}
}
}
return targetObj;
}