物件的深拷貝和淺拷貝和拷貝方法
阿新 • • 發佈:2020-08-15
我們知道物件在記憶體中分兩塊儲存,引用地址存放在棧記憶體,而本身的資料是存放在堆記憶體
所以我們區別是否是深拷貝或者淺拷貝可以觀察修改拷貝後的物件的屬性值之後原物件的該屬性值是否改變;
淺拷貝的物件和原物件都指向同一塊引用空間,只是引用地址不同罷了; 如圖所示
下面進行深拷貝和淺拷貝的方法總結;
1 ,淺拷貝方法
① 使用es6的擴充套件運算子
let obj = { a: 1, b :[1,2,3], c: { name: 'qq', age: 12 } } let o = {...obj}; o.c.name='zq'; // 此時源物件也會改變
② 陣列slice 進行陣列淺拷貝
let arr = [1,3,4]
let newarr = arr.slice()
2. 深拷貝方法
① JSON.parse(JSON.stringfy(obj)) 進行深拷貝 物件裡面的函式會丟失,同時undefined 也會丟失,正則等也會丟失
let obj = {
a:1,
b:[1,2,3],
c:{name: 'qq',age: 12},
d: null,
e: undefined,
f: /\$[a-zA-Z_]+/g
}
let b = JSON.parse(JSON.stringify(obj));
b 得到 {"a":1,"b":[1,2,3],"c":{"name":"qq","age":12},"d":null,"f":{}}"
② 使用遞迴實現深拷貝
function deepClone(obj, hash = new WeakMap()){ // 判斷特殊值 if(obj == null) return obj; // null undefined 不進行拷貝操作 if(obj instanceof Date) return new Date(obj) // 產生了 一個新的日期物件 if(obj instanceof RegExp) return newRegExp(obj); // 正則物件 // 物件或者普通值 if(typeof obj !== 'object') return obj; if(hash.get(obj)) return hash.get(obj) // 避免迴圈引用 let cloneObj = new obj.constructor; // 通過constructor 獲取到obj的建構函式 產生一個新物件 ,可以避免判斷值是物件或者陣列 hash.set(obj,cloneObj) // 讓生成的克隆物件先放入weakMap中; for (let key in obj) { if (obj.hasOwnProperty(key)) { cloneObj[key] = deepClone(obj[key],hash); } } return cloneObj; } let obj = {name:1, address:{x:10}}; obj.o = obj; let d = deepClone(obj) console.log(d,{depth: 10});