JavaScript有兩種數據類型,基礎數據類型和引用數據類型。基礎數據類型都是按值訪問的,咱們能夠直接操做保存在變量中的實際的值。而引用類型如Array,咱們不能直接操做對象的堆內存空間。引用類型的值都是按引用訪問的,即保存在變量對象中的一個地址,該地址與堆內存的實際值相關聯。javascript
1、深拷貝和淺拷貝的區別java
淺拷貝(shallow copy):只複製指向某個對象的指針,而不復制對象自己,新舊對象共享一塊內存;
深拷貝(deep copy):複製並建立一個一摸同樣的對象,不共享內存,修改新對象,舊對象保持不變。web
var a = 25; var b = a; b = 10; console.log(a);//25 console.log(b);//10 //淺拷貝 var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = obj1; obj2.b = 40; console.log(obj1);// { a: 10, b: 40, c: 30 } console.log(obj2);// { a: 10, b: 40, c: 30 } //深拷貝 var obj1 = { a: 10, b: 20, c: 30 }; var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c }; obj2.b = 40; console.log(obj1);// { a: 10, b: 20, c: 30 } console.log(obj2);// { a: 10, b: 40, c: 30 }
2、淺拷貝的實現json
var json1 = {"a":"name","arr1":[1,2,3]} function copy(obj1) { var obj2 = {}; for (var i in obj1) { obj2[i] = obj1[i]; } return obj2; } var json2 = copy(json1); json1.arr1.push(4); alert(json1.arr1); //1234 alert(json2.arr1) //1234
3、深拷貝的實現spa
一、Object.assign()
指針
let foo = { a: 1, b: 2, c: { d: 1, } } let bar = {}; Object.assign(bar, foo); foo.a++; foo.a === 2 //true bar.a === 1 //true foo.c.d++; foo.c.d === 2 //true bar.c.d === 1 //false bar.c.d === 2 //true
Object.assign()
是一種能夠對非嵌套對象進行深拷貝的方法,若是對象中出現嵌套狀況,那麼其對被嵌套對象的行爲就成了普通的淺拷貝。code
二、轉成JSON對象
用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象。blog
var obj1 = { body: { a: 10 } }; var obj2 = JSON.parse(JSON.stringify(obj1)); obj2.body.a = 20; console.log(obj1); // { body: { a: 10 } }
console.log(obj2); // { body: { a: 20 } }
console.log(obj1 === obj2); // false
console.log(obj1.body === obj2.body); // false
但這種方法的缺陷是會破壞原型鏈,而且沒法拷貝屬性值爲function的屬性遞歸
三、遞歸
採用遞歸的方法去複製拷貝對象
var json1={"name":"shauna","age":18,"arr1":[1,2,3,4,5],"string":'got7',"arr2":[1,2,3,4,5],"arr3":[{"name1":"shauna"},{"job":"web"}]}; var json2={}; function copy(obj1,obj2){ var obj2=obj2||{}; for(var name in obj1){ if(typeof obj1[name] === "object"){ obj2[name]= (obj1[name].constructor===Array)?[]:{}; copy(obj1[name],obj2[name]); }else{ obj2[name]=obj1[name]; } } return obj2; } json2=copy(json1,json2) json1.arr1.push(6); alert(json1.arr1); //123456
alert(json2.arr1); //12345