區別
深拷貝是遞歸復制了所有的層級 --------- 在堆中重新分配內存,并且把源對象的所有屬性都進行新建拷貝,以保證深拷貝的對象的引用圖不包含任何原有對象或對象圖上的任何對象,拷貝后的對象與原來的對象是完全隔離,互不影響。
淺拷貝是復制一層對象的屬性 -------- 淺拷貝是拷貝引用,拷貝后的引用都是指向同一個對象的實例,彼此之間的操作會影響互相操作
淺拷貝
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;
}