var a=1
操做的是變量實際保存的值。a = 2;函數
基本類型變量的複製:從一個變量向一個變量複製時,會在棧中建立一個新值,而後把值複製到爲新變量分配的位置上。var b= a;
棧內存spa
vara = new Object();
當操做時,須要先從棧中讀取內存地址,而後再延指針找到保存在堆內存中的值再操做
a.name= 'xz';插件
引用類型變量的複製:複製的是存儲在棧中的指針,將指針複製到棧中未新變量分配的空間中,而這個指針副本和原指針指向存儲在堆中的同一個對象;複製操做結束後,兩個變量實際上將引用同一個對象。所以,在使用時,改變其中的一個變量的值,將影響另外一個變量。
var b= a;3d
淺拷貝就是拷貝相同的引用地址,跟第六張圖同樣。
深拷貝則是引用地址也發生了改變。指針
1),拷貝的對象的值中若是有函數、undefined、symbol則通過JSON.stringify()序列化後的JSON字符串中這個鍵值對會消失
2),沒法拷貝不可枚舉的屬性,沒法拷貝對象的原型鏈
3),拷貝Date引用類型會變成字符串
4),拷貝RegExp引用類型會變成空對象
5),對象中含有NaN、Infinity和-Infinity,則序列化的結果會變成null
6),沒法拷貝對象的循環應用(即obj[key] = obj)
因此這個通常只適合純數據對象code
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};
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));
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