ES6復制拷貝數組,對象,json數組
擴展運算符的應用spread打散數組[...]
(1)復制數組
數組是復合的數據類型,直接復制的話,只是復制了指向底層數據結構的指針,而不是克隆一個全新的數組。
const a1 = [1, 2]; const a2 = a1; a2[0] = 2; a1 // [2, 2]
上面代碼中,a2
並不是a1
的克隆,而是指向同一份數據的另一個指針。修改a2
,會直接導致a1
的變化。
ES5 只能用變通方法來復制數組。
const a1 = [1, 2]; const a2 = a1.concat(); a2[0] = 2; a1 // [1, 2]
上面代碼中,a1
會返回原數組的克隆,再修改a2
a1
產生影響。
擴展運算符提供了復制數組的簡便寫法。
const a1 = [1, 2]; // 寫法一 const a2 = [...a1]; // 寫法二 const [...a2] = a1;
上面的兩種寫法,a2
都是a1
的克隆。
對象及json數組的拷貝,Object.assign() {...obj} JSON.Parse 等幾種拷貝的區別
let obj = { age: 10 } let obj1 = { grade: 1, name: { first: ‘bob‘ } } let objS = obj1 let objA= Object.assign(obj, obj1) let objJ = JSON.parse(JSON.stringify(obj1)) let objK = { ...obj1 } console.log(objA) console.log(objJ) console.log(objK) obj1.grade = 9 obj1.name.first = ‘chris‘ console.log(objS) console.log(objA) console.log(objJ) console.log(objK)
打印結果:
{ age: 10, grade: 1, name: { first: ‘bob‘ } }
{ grade: 1, name: { first: ‘bob‘ } }
{ grade: 1, name: { first: ‘bob‘ } }
{ grade: 9, name: { first: ‘chris‘ } }
{ age: 10, grade: 1, name: { first: ‘chris‘ } }
{ grade: 1, name: { first: ‘bob‘ } }
{ grade: 1, name: { first: ‘chris‘ } }
結論: 由於對象創建在堆上 棧上的變量保存其地址 所以也叫指針變量
淺拷貝 如let simpleObj = obj;
則只拷貝了 obj在棧上的指針變量給 simpleObj 也就是說simpleObj實際存儲的值是 obj的對象的內存地址 指向與 obj同樣的堆內存地址 所以改變 obj的值 simpleObj 的值也會改變
深拷貝 就是copy了一份對象 放在另一塊堆內存地址 改變之前的對象 對這個復制的對象不會有任何影響
js裏有幾種深拷貝方式
Object.assign() 不算深拷貝 也不算淺拷貝 一級拷貝 如果內層還有引用類型 就是淺拷貝了
... 擴展和 assign 一樣
JSON.parse(JSON.Stringify()) 深拷貝 但是缺點是不能拷貝 constructor 方法 解決辦法就是遞歸
ES6復制拷貝數組,對象,json數組