深拷貝 vs 淺拷貝

2021-09-13 02:23:53 字數 2463 閱讀 6219

深拷貝和淺拷貝都是針對的引用型別,js中的變數型別分為值型別(基本型別)和引用型別;對值型別進行複製操作會對進行乙份拷貝,而對引用型別賦值,則會進行位址的拷貝,最終兩個變數指向同乙份資料。

// 基本型別

var a = 1;

var b = a;

a = 2;

console.log(a, b); // 2, 1 ,a b指向不同的資料

// 引用型別指向同乙份資料

var a = ;

var b = a;

a.c = 2;

console.log(a.c, b.c); // 2, 2 全是2,a b指向同乙份資料

對於引用型別,會導致a b指向同乙份資料,此時如果對其中乙個進行修改,就會影響到另外乙個,有時候這可能不是我們想要的結果,如果對這種現象不清楚的話,還可能造成不必要的bug。那麼如何切斷a和b之間的關係呢,可以拷貝乙份a的資料,根據拷貝的層級不同可以分為淺拷貝和深拷貝,淺拷貝就是只進行一層拷貝,深拷貝就是無限層級拷貝。

深複製和淺複製最根本的區別在於是否是真正獲取了乙個物件的複製實體,而不是引用

var a1 = };

var a2 = shallowclone(a1); // 淺拷貝

a2.b.c === a1.b.c // true

var a3 = clone(a1); // 深拷貝

a3.b.c === a1.b.c // false

所謂的淺複製,只是拷貝了基本型別的資料,而引用型別資料,複製後也是會發生引用,我們把這種拷貝叫做「(淺複製)淺拷貝」。object.assign({}, obj1, obj2)
淺拷貝的實現
function shallowclone(source) ;

for(var i in source)

}return target;

}

深拷貝的實現

深拷貝的問題其實可以分解成兩個問題,淺拷貝+遞迴,什麼意思呢?假設我們有如下資料

var a1 = };
只需稍加改動上面淺拷貝的**即可,注意區別

function clone(source) ;

for(var i in source) else }}

return target;

}

其實上面的**問題太多了,先來舉幾個例子吧

function isobject(x) 

function clone(source)

方法: 用系統自帶的json來做深拷貝的例子,下面來看下**實現

function clonejson(source)
但是clonejson也有缺點,它的內部也是使用遞迴的方式

clonejson(createdata(10000)); // maximum call stack size exceeded

既然是用了遞迴,那迴圈引用呢?並沒有因為死迴圈而導致棧溢位啊,原來是json.stringify內部做了迴圈引用的檢測,正是我們上面提到破解迴圈引用的第一種方法:迴圈檢測

var a = {};

a.a = a;

clonejson(a) // uncaught typeerror: converting circular structure to json

如何複製物件而不發生引用呢,對於陣列,es6我們複製有新的兩種方法,不會發生引用。

第一種:array.from(要複製的陣列);

var arr1=[1,2,3];

var arr2=array.from(arr1);

arr1.push(4);

alert(arr1); //1234

alert(arr2); //123

arr2.push(5);

alert(arr1); //1234

alert(arr2); //1235

第二種:...

var arr1=[1,2,3];

var arr2=[...arr1];

arr1.push(4);

alert(arr1); //1234

alert(arr2); //123

arr2.push(5);

alert(arr1); //1234

alert(arr2); //1235

第二種這個方法也可以用在函式的行參上面。

function show(...arr1)

show(1,2,3,4)

深拷貝VS淺拷貝 巷子

1 回顧 資料傳遞的方法 值傳遞 基本資料型別的資料不會發改變,因為基本資料型別一般存放在棧裡面,值傳遞只是將資料拷貝了乙份給另乙個變數 例如 值傳遞 var a 10 var b a b 10 console.log a 10 console.log b 20 引用傳遞 var arr 10,20...

C 之深拷貝VS淺拷貝

1.淺拷貝 將值直接拷貝過去 只是對指標的拷貝,拷貝之後兩個指標指向同一塊記憶體,會造成系統奔潰 class array include include array.h using namespace std array array int count array array const array...

淺拷貝 深拷貝

copy mutablecopy copy 不管是可變的,還是不可變的,結果都是不可變的 mutablecopy 不管是不可變的,還是可變的,結果都是可變的 nsmutablestring str nsmutablestring stringwithformat a nsarray arr1 str...