js 淺拷貝與深拷貝

2021-08-29 16:10:58 字數 3189 閱讀 2809

js 有兩種資料型別,基礎資料型別和引用資料型別;基礎資料型別都是按值訪問的,我們可以直接操作儲存在變數中的實際的值。而引用型別如array,

1.淺拷貝:只複製指向某個物件的指標,而不複製物件本身,新舊物件共享一塊記憶體;

淺拷貝是指只複製一層物件,當物件的屬性是引用型別時,實質複製的是其引用,當引用指向的值改變時也會跟著變化

案例:

// 引用型別

let obj1 = ;

let obj2 = obj1;

obj1.b = 60;

// 或

// obj2.b = 50;

console.log(obj1);

console.log(obj2);

let array1 = [0, 1, 2, 3, 4];

let array2 = array1;

console.log(array1 === array2);

array1[0] = 1;

console.log(array1, array2);

2.深拷貝:複製並建立乙個一摸一樣的物件,不共享記憶體,修改新物件,舊物件保持不變。

基礎資料型別

let a = 'zjl';

let b = a;

a = 'zmf';

// 或

// b='dwb';

console.log('a:' + a + ' ' + 'b:' + b);

所以當你此時修改a='zmf',對b並不會造成影響,因為此時的b已自食其力,不受a的影響了。當然,let a='zjl',b=a;雖然b不受a影響,但這也算不上深拷貝,因為深拷貝本身只針對較為複雜的object型別資料。

// 這裡再次強調,深拷貝,是拷貝物件各個層級的屬性,可以看個例子。jq裡有乙個extend方法也可以拷貝物件,我們來看看

let array3 = [1, 3, 4, 2, 5];

let array4 = array3.slice();

array3[0] = 10;

array4[0] = 20;

console.log(array3, array4);

// 那是不是說slice方法也是深拷貝了,畢竟array4也沒受array3的影響,上面說了,深拷貝是會拷貝所有層級的屬性,還是這個例子,我們把array3改改

let array5 = [1, 3, 5, 2, [2, 3], 4, 5];

let array6 = array5.slice();

array5[4][0] = 4;

// array6[4][0]=5;

console.log(array5, array6);

// 拷貝的不徹底啊,array6物件的一級屬性確實不受影響了,但是二級屬性還是沒能拷貝成功,仍然脫離不了array5的控制,說明slice根本不是真正的深拷貝。

下面就來說說深拷貝的一些方法

1.遞迴

看這個之前可以去看看遞迴演算法

let json1 = , ] };

let json2 = {};

function copy(obj1, obj22) ;

for (let name in obj1) ;

copy(obj1[name], obj22[name]);

} else

}return obj22;

}json2 = copy(json1, json2);

json1.arr1.push(6);

console.log(json1.arr1, json2.arr1);

// 1.2

function deepclone(obj3) ;

if (obj3 && typeof obj3 === "object") else }}

}return objclone;

}let obja = [1, 2, 3, 4],

objb = deepclone(obja);

obja[0] = 2;

console.log(obja, objb);

2.json物件的parse和stringify 但這種方法的缺陷是會破壞原型鏈,並且無法拷貝屬性值為function的屬性

function jsoncopy(objj) 

let jsona = [0, 1, [2, 3], }, 4]; //這裡加了function這個物件,這個物件不能被拷貝過去

let jsonb = jsoncopy(jsona);

jsona[2][1] = 6;

jsonb[2][1] = 7;

console.log(jsona, jsonb);

3.es6 object.assign():object.assign()是一種可以對非巢狀物件進行深拷貝的方法,如果物件中出現巢狀情況,那麼其對被巢狀物件的行為就成了普通的淺拷貝。

let zjl = 

}let zmf = {};

object.assign(zmf, zjl);

zjl.a++;

zjl.a === 2 //true

zmf.a === 1 //true

zjl.c.d++;

zjl.c.d === 2 //true

zmf.c.d === 1 //false

zmf.c.d === 2 //true

4.jq的extend方法

$.extend([deep], target, object1[, objectn])

deep表示是否深拷貝,為true為深拷貝,為false,則為淺拷貝

target object型別 目標物件,其他物件的成員屬性將被附加到該物件上。

object1 objectn可選。 object型別 第乙個以及第n個被合併的物件。

let jqa = [0, 1, [2, 3], 4],

jqb = $.extend(true, , jqa);

jqa[0] = 1;

jqa[2][0] = 1;

console.log(a, b);

js深拷貝與淺拷貝

1 基礎知識 基本型別與引用型別 js中可以把變數分成兩部分,基本型別和引用型別。基本型別包括 undefined null boolean number和string 引用型別值可能由多個值構成的物件。在對基礎型別資料進行拷貝時,實際相當於建立新的相同資料 hello 賦值給b var a hel...

js深拷貝與淺拷貝

實現乙個頁面或者乙個功能時,常常遇到的場景需要我們備份乙個陣列或者物件,這時候出現了深拷貝與淺拷貝效果截然不同呀總結如下 var arr 1,2,3,4 shallowarr arr arr 0 change console.log arr console.log shallowarr change...

JS 深拷貝與淺拷貝

參考學習 在有指標的情況下,淺拷貝只是增加了乙個指標指向已經存在的記憶體,而深拷貝就是增加乙個指標並且申請乙個新的記憶體,使這個增加的指標指向這個新的記憶體。深拷貝 陣列 法一 for迴圈 let arr1 1,2,3 let arr2 copyarr arr1 function copyarr a...