一、淺拷貝
在JavaScript中,拷貝可以看成是將一個數據類型中的值,複製到另一個數據類型中的過程。淺拷貝是將原始對象第一層屬性的內存地址複製到目標對象的內存地址中,換言之,淺拷貝只是複製了內存中的地址,兩邊操作同一塊內存,也因此在淺拷貝中,改變其中一個變量可能會對另一個變量產生影響。
舉個例子:
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
obj1.a = 4;
console.log(obj2.a); // 輸出:1
在上面的例子中,我們將obj1複製到obj2中,然後修改obj1的a屬性為4,那麼obj2的a屬性不會被改變,還是保持原來的1。這是因為,Object.assign()是淺拷貝,只是將第一層屬性值複製到了新的變量中,所以obj2中的值是和obj1相同,但是兩者是不同的變量。
二、深拷貝
相對淺拷貝,深拷貝就是將原始對象的所有屬性(包括第一層和嵌套的屬性)遞歸地複製到目標對象中。在JavaScript中,我們通常使用遞歸的方式來實現深拷貝。
舉個例子:
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj1.b.c = 3;
console.log(obj2.b.c); // 輸出:2
在上面的例子中,我們使用JSON.stringify將obj1轉成字符串,再用JSON.parse將其轉成對象,這樣就可以實現深拷貝了。當我們改變obj1的b屬性中的c屬性的值時,obj2並不會被改變,因為obj1和obj2是不同的變量。
三、淺拷貝的實現方式
JavaScript中,我們可以使用以下方式來實現淺拷貝:
1. Object.assign()
Object.assign()方法可以將一個或多個源對象的所有可枚舉屬性複製到目標對象中,並返回目標對象。只有第一層屬性值被複制,如果存在相同屬性,後面的屬性會覆蓋前面的屬性。注意,Object.assign()是淺拷貝,只複製第一層屬性。
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = Object.assign({}, obj1);
2. 擴展運算符
擴展運算符可以將一個對象的可枚舉屬性拷貝到另一個對象中,同樣只能實現淺拷貝。
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = {...obj1};
四、深拷貝的實現方式
JavaScript中,我們可以使用以下方式來實現深拷貝:
1. 遞歸實現
遞歸實現深拷貝是最常用的實現方式。通過遞歸將嵌套對象的每一層都複製到新的變量中,從而實現了完整的拷貝。需要注意的是,在遇到循環引用或者包含函數等其他類型時,需要進行特殊處理。
function deepClone(obj){
if(typeof obj !== 'object' || obj === null){
return obj;
}
let newObj = Array.isArray(obj) ? [] : {};
for(let key in obj){
newObj[key] = deepClone(obj[key]);
}
return newObj;
}
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = deepClone(obj1);
2. JSON.parse & JSON.stringify
我們前面已經提到過,可以使用JSON.stringify將對象轉成字符串,然後再用JSON.parse將其轉成對象,從而實現深拷貝。需要注意的是,使用JSON.stringify & JSON.parse無法拷貝函數和循環引用。
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = JSON.parse(JSON.stringify(obj1));
3. Lodash庫
Lodash是一個流行的JavaScript實用工具庫,其中提供了_.cloneDeep方法,支持深拷貝。
let obj1 = { a: 1, b: { c: 2 } };
let obj2 = _.cloneDeep(obj1);
五、總結
在JavaScript中,淺拷貝和深拷貝是兩種常用的拷貝方式。淺拷貝只複製第一層的屬性,複製後的變量和原變量指向同一塊內存;深拷貝則遞歸複製所有的屬性,複製後的變量和原變量是完全獨立的變量。淺拷貝可以使用Object.assign和擴展運算符等簡單方式實現,深拷貝則需要使用遞歸、JSON.parse & JSON.stringify或者Lodash庫等方式實現。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/236320.html
微信掃一掃
支付寶掃一掃