對象類型在賦值的過程中其實是復(fù)制了地址葛假,這樣會導(dǎo)致一方改變的時候其他地方也都會被改變的情況
例:
let a = {
age: 1
}
let b = a;
a.age = 2;
console.log(b.age); // 2
這種情況下我們就可以使用淺拷貝來解決這個問題
淺拷貝
淺拷貝只是拷貝基本類型的數(shù)據(jù)障陶,如果父對象的屬性等于數(shù)組或另一個對象,那么實際上聊训,子對象獲得的只是一個內(nèi)存地址,因此存在父對象被篡改的可能带斑,淺拷貝只復(fù)制指向某個對象的指針,而不復(fù)制對象本身勋拟,新舊對象還是共享同一塊內(nèi)存
1敢靡、Object.assign
這個屬性并不是用來實現(xiàn)深拷貝的赶站,相反可以用來實現(xiàn)淺拷貝纺念。Object.assign只會拷貝所有的屬性到新的對象中贝椿,如果屬性值是對象的活,拷貝的就是地址,所以不是深拷貝
例:
let a = {
age: 1
};
let b = Object.assign({}, a);
a.age = 2;
console.log(b.age); // 1
2渣窜、展開運算符 ...
let a = {
age: 1
};
let b = {...a};
a.age = 2;
console.log(b.age); // 1
但是淺拷貝只能解決第一層的問題铺根,如果對象下邊的值還有對象的話,那么還是會有問題乔宿,如果想繼續(xù)解決就要使用深拷貝了夷都。
問題實例:
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = { ...a }
a.jobs.first = 'native'
console.log(b.jobs.first) // native
深拷貝
深拷貝就是能夠?qū)崿F(xiàn)真正意義上的數(shù)組和對象的拷貝。遞歸調(diào)用"淺拷貝"予颤。(深拷貝會另外創(chuàng)造一個一模一樣的對象囤官,新對象跟原對象不共享內(nèi)存,修改新對象不會改到原對象)
通掣蚺埃可以通過
JSON.parse(JSON.stringify(object));
解決
let a = {
age: 1,
jobs: {
first: 'FE'
}
}
let b = JSON.parse(JSON.stringify(a))
a.jobs.first = 'native'
console.log(b.jobs.first) // FE
但是這種方法也有局限性
- 會忽略undefined
- 會忽略symbol
- 不能序列化函數(shù)
- 不能解決循環(huán)引用的對象
例如
let obj = {
a: 1,
b: {
c: 2,
d: 3,
},
}
obj.c = obj.b
obj.e = obj.a
obj.b.c = obj.c
obj.b.d = obj.b
obj.b.e = obj.b.c
let newObj = JSON.parse(JSON.stringify(obj))
console.log(newObj)
js實現(xiàn)深拷貝具體方法
// 深拷貝
function deepClone(obj, hash = new WeakMap()) {
if (obj == null) {
return obj;
}
if (obj instanceof Date) {
return new Date(obj);
}
if (obj instanceof RegExp) {
return new RegExp(obj);
}
if (typeof obj !== 'object') {
return obj;
}
if (hash.has(obj)) {
return hash.get(obj);
}
let cloneObj = new obj.constructor;
hash.set(obj, cloneObj);
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
cloneObj[key] = deepClone(obj[key], hash);
}
}
return cloneObj;
}
本篇文章只是自己對深淺拷貝的一個簡單理解党饮,也參考了一些其他文章
參考文獻:
https://juejin.im/book/5bdc715fe51d454e755f75ef/section/5bed40d951882545f73004f6