深拷貝與淺拷貝

2021-09-24 07:53:55 字數 4360 閱讀 1617

基本的資料型別有:undefinedbooleannumberstringnull,symbol

基本型別的訪問是按值訪問的,就是說你可以操作儲存在變數中的實際的值。

任何方法都無法改變乙個基本型別的值。

var str = 'abc123';

str.replace('abc', 123); // '123123'

console.log(str); // 'abc123'

複製**

基本型別的比較是值的比較。

基本型別的值是存放在棧記憶體中。

除基本型別之外就是引用資料型別,也可以說就是物件了(object,array,function,math,data,regexp等)。

引用型別的值是可變的。

引用型別的值是同時儲存在棧記憶體和堆記憶體中的物件。

引用型別的比較是引用的比較

// 對基本資料型別的直接賦值是深拷貝

var a = 1;

b = a;

a = 2;

console.log(a); // 2

console.log(b); // 1

// 對引用資料型別的直接賦值是淺拷貝(拷貝的是引用的位址)

var obj1 = ;

var obj2 = obj1;

obj1.age = 32;

console.log(obj1.age); // 32

console.log(obj2.age); // 32

複製**

1、陣列的拷貝
// 淺拷貝,直接賦值

var a = [1,2,3,4,5];

var b = a;

a[0] = 2;

console.log(a); // [2, 2, 3, 4, 5]

console.log(b); // [2, 2, 3, 4, 5]

複製**

// cancat,簡單陣列的深拷貝

var a = [1,2,3,4,5];

var b = .concat(a);

a[0] = 2;

console.log(a); // [2, 2, 3, 4, 5]

console.log(b); // [1, 2, 3, 4, 5]

複製**

// slice,簡單陣列的深拷貝

var a = [1,2,3,4,5];

var b = a.slice();

a[0] = 2;

console.log(a); // [2, 2, 3, 4, 5]

console.log(b); // [1, 2, 3, 4, 5]

複製**

// ...運算子,簡單陣列的深拷貝

var a = [1,2,3,4,5];

var b = [...a];

a[0] = 2;

console.log(a); // [2, 2, 3, 4, 5]

console.log(b); // [1, 2, 3, 4, 5]

複製**

cancat,slice,...運算子的不足

var a = [1,[1,2],3,4,5];

var b = a.slice();

a[0] = 2;

a[1][0] = 2;

console.log(a); // [2, [2,2], 3, 4, 5]

console.log(b); // [1, [2,2], 3, 4, 5]

複製**

var a = [1,[1,2],3,4,5];

var b = .concat(a);

a[0] = 2;

a[1][0] = 2;

console.log(a); // [2, [2,2], 3, 4, 5]

console.log(b); // [1, [2,2], 3, 4, 5]

複製**

var a = [1,[1,2],3,4,5];

var b = [...a];

a[0] = 2;

a[1][0] = 2;

console.log(a); // [2, [2,2], 3, 4, 5]

console.log(b); // [1, [2,2], 3, 4, 5]

複製**

從上面的結果可以看到,cancat,slice,...運算子只能對陣列的一級元素為基本型別的資料實現深拷貝,對於引用型別的元素還是淺拷貝。

2、物件的拷貝

...運算子

var obj1 =  

};var obj2 = ;

obj1.name = 'lisi';

obj1.age = 42;

obj1.team.name = 'test';

obj1.team.number = 20;

console.log(obj1); // }

console.log(obj2); // }

複製**

object.assign()方法

var obj1 =  

};var obj2 = object.assign({}, obj1);

obj1.name = 'lisi';

obj1.age = 42;

obj1.team.name = 'test';

obj1.team.number = 20;

console.log(obj1); // }

console.log(obj2); // }

複製**

從上面可以看到...運算子object.assign()方法也只能實現對一級資料為基本資料型別的拷貝,對於一級資料型別為引用型別的資料無法實現深拷貝。

3、 使用json.parsejson.stringify

var a = [1,[1,2],3,4,5];

var b = json.parse(json.stringify(a));

a[0] = 2;

a[1][0] = 2;

console.log(a); // [2, [2,2], 3, 4, 5]

console.log(b); // [1, [1,2], 3, 4, 5]

複製**

var obj1 =  

};var obj2 = json.parse(json.stringify(obj1));

obj1.name = 'lisi';

obj1.age = 42;

obj1.team.name = 'test';

obj1.team.number = 20;

console.log(obj1); // }

console.log(obj2); // }

複製**

ps: 並不是所有的資料型別都可以被json.stringify

4、遞迴

// 此方法僅僅提供思路,並非最佳實踐

function deepclone(target, type) ;

if(typeof target === 'object') else }}

} return

clonedata

}var obj1 =

} };var obj2 = deepclone(obj1, true);

obj1.name = 'lisi';

obj1.age = 42;

obj1.team.name = 'test';

obj1.team.number = 20;

obj1.team.person =

console.log(obj1); //

console.log(obj2); //

複製**

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...

淺拷貝與深拷貝

淺拷貝 1 2 myclass a,b a b 為了封裝性和解耦,同型別的兩個物件之間進行賦值操作時,所有成員變數被複製,包括私有成員 指標變數。類的成員函式在傳遞或返回物件時都會進行物件複製產生臨時物件,比如函式呼叫時實參變為形參,以及函式返回物件。考慮到效能和使用者要求不同,編譯器不複製物件內部...

「淺拷貝」與「深拷貝」

c 中物件的複製就如同 轉殖 用乙個已有的物件快速地複製出多個完全相同的物件。一般而言,以下三種情況都會使用到物件的複製 1 建立乙個新物件,並用另乙個同類的已有物件對新物件進行初始化,例如 cpp view plain copy class rect rect rect1 rect rect2 r...