淺談深拷貝和淺拷貝及幾種實現方法
阿新 • • 發佈:2018-11-18
rgb bsp for ace onos 都是 UNC get con 討論深拷貝與淺拷貝之前,要先回顧一下值傳遞與引用傳遞:
值傳遞:
var a = 10;
var b = a;
b++;
//console.log(a,b)//a:10 b:11
引用傳遞:
var arr = [10,20,30,40];
var arr1 = arr;
arr1[0] = 40;
//console.log(arr,arr1);//[40,20,30,40] [40,20,30,40]
一、淺拷貝(引用傳遞)
(1)概念
淺拷貝:
當一個對象拷貝另一個對象的數據的時候,只要一個對象的數據發生改變另一個對象的數據也會發生改變
因為淺拷貝拷貝的是引用的地址,(所以必須在對象是多層才能拷貝,單層拷貝的是數值,多層說明裏面套著對象,所以拷貝的是地址。)
(2)實現方式
方法一(ES6的方法):
Object.assign() 作用:將第二個參數及以後的參數合並到第一個對象裏。
參數1:target
參數2:對象......
參數3:對象....
例:
var obj = {a:{name:"kaiqin",age:19}};
var obj1 = Object.assign({},obj);
obj1.a.name="wang"
console.log(obj1)
console.log(obj)
方法二:使用 for in 循環,遍歷每一個屬性,將他們賦值給新的對象。 要求對象必須是多層的狀態下才能實現淺拷貝
var obj = { a: {name:"kaiqin",age:19 } } ;
var obj2 = {a:1,b:2,c:3};
//多層
function copy(obj){
var newObj = {};
for(var key in obj){
newObj[key] = obj[key];
}
return newObj;
}
//單層
var obj1 = copy(obj);
obj1.a.name="wang"
console.log(obj1)
console.log(obj)
方法三:$.extend()
除了可以給jquery對象擴展方法外還可以實現深淺拷貝
1、布爾值 如果填true的情況下是深考貝 什麽也不寫就是淺拷貝
2、目標對象
3......後面所有的對象 都是需要合並的對象
var obj = {a:{name:"kaiqin",age:19}};
var obj1 = {b:{name:"wang",age:19}};
var obj2 = $.extend({},obj,obj1)
obj2.a.name="zhang";
console.log(obj2)
console.log(obj)
二、深拷貝
(1)概念
當一個對象拷貝另一個對象的數據的時候,其中一個對象的數據發生變化不會影響另一個對象的數據
因為深考貝拷貝的是對象的數據而不是地址
(2)實現方法
方法一:對象是單層的情況下
Object.assign()
var obj = {a:1,b:2,c:3}
var obj1 = Object.assign({},obj);
obj1.a = 30;
console.log(obj1,obj)
方法二:差不多比較完美
$.extend()
除了可以給jquery對象擴展方法外還可以實現深淺拷貝
1、布爾值 如果填true的情況下是深考貝 什麽也不寫就是淺拷貝
2、目標對象
3......後面所有的對象 都是需要合並的對象
var obj = {a:{name:"kaiqin",age:19}};
var obj1 = {b:{name:"wang",age:19}};
var obj2 = $.extend(true,{},obj,obj1);
obj2.a.name="zhang";
console.log(obj2)
console.log(obj)
方法三:JSON.parse、JSON.stringfiy 不能拷貝函數,但用在拷貝數據庫數據時,不影響。因為數據庫沒有函數。所以推薦使用
其原理是:先將對象轉換為字符串、再轉換成對象,此時地址一定發生了變化,所以可以實現淺拷貝。
var obj1 = {b:{name:"wang",age:19}};
var obj2 = JSON.parse(JSON.stringify(obj1)); //此時地址發生了改變。
obj2.b.name = "kaiqin";
console.log(obj1,obj2)
淺談深拷貝和淺拷貝及幾種實現方法