深淺拷貝針對的是 對象類型,若是是字符串的數組用[...arr],仍是不會影響 數組
要區分針對數組的深淺拷貝(默認狀況爲裏面沒有對象的數組),與針對對象的深淺拷貝數據結構
let a1 = [1, 2]; let a2 = a1; a2[0] = 2; a1 // [2, 2] 這個是複製了指向底層數據結構的指針 -- let a1 = [1, 2]; let a2 = [...a1]; 這個是a1會返回原數組的克隆,再修改a2就不會對a1產生影響 -- let a1 = [{foo:1}]; let a2 = [...a1]; a1[0].foo=2 a2[0].foo ===>2 這時a1數組裏是對象,a2克隆過去的話,對象裏的值仍是會隨着修改 深拷貝廣泛的方法是對對象的子對象進行遞歸拷貝 // 遞歸實現一個深拷貝 function deepClone(source){ if(!source || typeof source !== 'object'){ throw new Error('error arguments', 'shallowClone'); } var targetObj = source.constructor === Array ? [] : {}; for(var keys in source){ if(source.hasOwnProperty(keys)){ if(source[keys] && typeof source[keys] === 'object'){ targetObj[keys] = source[keys].constructor === Array ? [] : {}; targetObj[keys] = deepClone(source[keys]); }else{ targetObj[keys] = source[keys]; } } } return targetObj; } 有一個用JSON對象中的parse和stringify來實現深拷貝 可是源對象的方法在拷貝的過程當中丟失了,這是由於在序列化JavaScript對象時,全部函數和原型成員會被有意忽略 // 利用JSON序列化實現一個深拷貝 function deepClone(source){ return JSON.parse(JSON.stringify(source)); } var o1 = { arr: [1, 2, 3], obj: { key: 'value' }, func: function(){ return 1; } }; var o2 = deepClone(o1); console.log(o2); // => {arr: [1,2,3], obj: {key: 'value'}}
對於字符串類型,淺複製是對值的複製,對於對象來講,淺複製是對對象地址的複製,並沒 有開闢新的棧,也就是複製的結果是兩個對象指向同一個地址,修改其中一個對象的屬性,則另外一個對象的屬性也會改變,而深複製則是開闢新的棧,兩個對象對應兩個不一樣的地址,修改一個對象的屬性,不會改變另外一個對象的屬性。深複製實現代碼以下:
第一種方法、經過遞歸解析解決
第二種方法:經過JSON解析解決
做者:六師兄Leon
連接: https://www.zhihu.com/questio...
function deepCopy(initalObject,finalObject){ var finalObject = finalObject || {} // 處理未輸入新對象的狀況 for(var key in initalObject){ if(initalObject[key] === initalObject){ continue } if(typeof initalObject[key] === "object"){ finalObject[key] = (initalObject[key].constructor === Array) ? [] : Object.create(initalObject[key]) //經過Object.create()方法構造新的對象 }else{ finalObject[key] = initalObject[key] } } return finalObject }