從原理看:html
從現象看:
A複製了B,B被修改後,數組
深拷貝針對的s複雜的object類型數據
∴如直接賦值的單層拷貝,如b=a,b雖然不受a的影響,可是這也不算作深拷貝
現象只是做爲方便理解的一個參考,真正的判斷標準仍是要從原理上看函數
數據類型分爲:spa
當b=a進行拷貝時,b複製的是a的引用地址,並非堆裏面的值,因此這便形成了當a發生改變,b也會隨之改變的淺拷貝.net
實現淺拷貝的方法:
1、 直接複製指針
//基本數據類型 var arr = [1, 2, 3, '4']; var arr2 = arr; arr2[1] = "test"; console.log(arr); // [1, "test", 3, "4"] console.log(arr2); // [1, "test", 3, "4"] //改變其中一個對象的屬性值,兩個對象都發生了改變 //obj和obj2兩個變量都指向同一個指針,賦值時只是複製了指針地址,它們指向同一個引用,∴當咱們改變其中一個的值,另外一個變量的值也會隨之改變 ---------- //對象級 function Clone(obj1){ var obj2 ={}; for(var i in obj1) { obj2[i]=obj1[i]; } return obj2; }
淺拷貝只是拷貝了一層,除了對象是拷貝引用類型,其餘的都是直接將值傳遞,有本身的內存空間code
2、ES6中的Object.assign()方法
該方法能夠把任意多個的源對象自身的可枚舉屬性拷貝給對象,而後返回目標對象htm
Object.assign(目標對象,任意多個源對象)
var obj1 = { a: "hello", b: { a: "hello", b: 21} }; var cloneObj1= Object.assign({}, obj1); cloneObj1.a = "changed"; cloneObj1.b.a = "changed"; console.log(obj1.a); //hello console.log(obj.b.a); // "changed"
若是對象只有一層,這個函數能夠做爲深拷貝的方法對象
var obj2 = { a: 10, b: 20, c: 30 }; var cloneObj2 = Object.assign({}, obj2); cloneObj2.b = 100; console.log(obj2); // { a: 10, b: 20, c: 30 } <-- 沒有改變,實現了深拷貝 console.log(cloneObj2); // { a: 10, b: 100, c: 30 }
若想實現深拷貝,就須要在堆中開闢一個內存,用來存放b的值。blog
方法1、手動複製
將A對象項的屬性逐個負責給另外一個對象的屬性
var ob1 = {a:1,b:2,c:3}; var ob2 = {a:ob1.a,b:ob1.b,c:ob1.c}; ob1.a = 0; ob2.b = 0; console.log(ob1);//023 console.log(ob2);//103
這樣很麻煩,且本質上不能算做深拷貝,當ob1內嵌套對象c時,ob1和ob2將共享c,當改變c的屬性時,ob1ob2將都發生改變
方法2、將對象經過JSON方法轉成字符串再轉回來
能夠實現真正的深拷貝,可是隻能用於能夠轉成JSON格式的對象,function沒法轉換成JSON,就不可以使用
∴此方法會捨棄對象的構造函數
var ob1 ={c:{a:1,b:2}}; var ob2 =JSON.parse(JSON.stringfy(ob1)); //用JSON.stringify把對象轉成字符串,再用JSON.parse把字符串轉成新的對象
方法3、遞歸拷貝
function deepClone(obj1,obj2){ var obj = obj2|| {};//若是obj存在則定義爲obj2,不然創建空對象 for(var i in obj1){//遍歷原對象 if(typeof obj1[i] === 'object'){//若是當前元素是對象 obj[i] = Array.isArray(obj1[i]) ?[]:{};//判斷是數組仍是對象 deepClone(obj1[i],obj[i]);//利用遞歸逐層遍歷直到最後一層 } else{ obj[i] = obj1[i];//賦值 } } return obj; } var str = {}; var obj = { a: {a: "Leemo", b: 19980228} }; deepClone(obj, str); console.log(str.a);
方法4、使用Object.create()方法
var Obj2 = object.create(Obj1); //實現Obj2深拷貝Obj1