深拷貝和淺拷貝

提及深淺拷貝其實就是數據內存,堆棧問題。

基本數據類型值指保存在棧內存中的簡單數據段

var a=1
1.png
操做的是變量實際保存的值。a = 2;
2.png函數

基本類型變量的複製:從一個變量向一個變量複製時,會在棧中建立一個新值,而後把值複製到爲新變量分配的位置上。var b= a;
棧內存
3.pngspa

引用數據類型:引用數據類型值指保存在堆內存中的對象。也就是,變量中保存的實際上的只是一個指針,這個指針指向內存中的另外一個位置,該位置保存着對象。訪問方式是按引用訪問。

vara = new Object();
ulStr8.png
當操做時,須要先從棧中讀取內存地址,而後再延指針找到保存在堆內存中的值再操做
a.name= 'xz';
ulS6MV.png插件

引用類型變量的複製:複製的是存儲在棧中的指針,將指針複製到棧中未新變量分配的空間中,而這個指針副本和原指針指向存儲在堆中的同一個對象;複製操做結束後,兩個變量實際上將引用同一個對象。所以,在使用時,改變其中的一個變量的值,將影響另外一個變量。
var b= a;
ulpPL8.png3d

因此深淺拷貝。就是對堆內存(複雜數據類型)而言。

淺拷貝就是拷貝相同的引用地址,跟第六張圖同樣。
深拷貝則是引用地址也發生了改變。指針

對象實現深拷貝的方案

1,經過JSON對象來回轉換。JSON.parse(JSON.stringify())

缺點:

1),拷貝的對象的值中若是有函數、undefined、symbol則通過JSON.stringify()序列化後的JSON字符串中這個鍵值對會消失
2),沒法拷貝不可枚舉的屬性,沒法拷貝對象的原型鏈
3),拷貝Date引用類型會變成字符串
4),拷貝RegExp引用類型會變成空對象
5),對象中含有NaN、Infinity和-Infinity,則序列化的結果會變成null
6),沒法拷貝對象的循環應用(即obj[key] = obj)
因此這個通常只適合純數據對象code

2,經過{}賦值建立,開闢新的引用地址,在將須要拷貝的鍵值放在新的堆內存裏面。實現深拷貝

a: {
        b: 1
    },
    c: 1
};
var obj2 = {};

obj2.a = {}
obj2.c = obj1.c
obj2.a.b = obj1.a.b;
console.log(obj1); //{a:{b:1},c:1};
console.log(obj2); //{a:{b:1},c:1};
obj1.a.b = 2;
console.log(obj1); //{a:{b:2},c:1};
console.log(obj2); //{a:{b:1},c:1};

3,經過插件,或第三方庫。

1.lodash
2.jQuery對象

var oldJson = {
  Name: 'quber',
  List: [1, 2, 3, 4],
  Obj: [
   { name: 'qubernet', fun: function () { return 1; } },
   { name: 'qubernet1', fun: function () { return 2; } }
  ]
};
var newJson = $.extend(true, {}, oldJson);
console.log(JSON.stringify(newJson));

4,本身封裝深拷貝方法

var obj1 = {
    a:{
        b:1
    }
};
function deepClone(obj) {
    var cloneObj = {}; //在堆內存中新建一個對象
    for(var key in obj){ //遍歷參數的鍵
       if(typeof obj[key] ==='object'){ 
          cloneObj[key] = deepClone(obj[key]) //值是對象就再次調用函數
       }else{
           cloneObj[key] = obj[key] //基本類型直接複製值
       }
    }
    return cloneObj 
}
var obj2 = deepClone(obj1);
obj1.a.b = 2;
console.log(obj2); //{a:{b:1}}

首先這個deepClone函數並不能複製不可枚舉的屬性以及Symbol類型
這裏只是針對Object引用類型的值作的循環迭代,而對於Array,Date,RegExp,Error,Function引用類型沒法正確拷貝
對象循環引用成環了的狀況
網上應該有更全的方法,能夠本身去嘗試blog

相關文章
相關標籤/搜索