深拷貝和淺拷貝
初識
js中數據分爲基本數據類型如null
、string
、undefined
、number
、boolean
、symbol
,以及引用數據類型如對象
和數組
。
而在js中存儲方式也是分棧和堆,基礎數據類型是棧存儲,引用數據類型一般是堆存儲。
深拷貝和淺拷貝是對於複雜類型而言的。
下面先通過一個簡單的例子進行說明其區別。
// 直接賦值
const initData = [ 1 , { obj: '123' } ];
const finalData = initData;
finalData[0] = 2;
finalData[1].obj = '456';
console.log(initData); // [ 2, { obj: '456' } ]
console.log(finalData); // [ 2, { obj: '456' } ]
// 基本數據類型
let str1 = '123';
str2 = str1;
str2 = '456';
console.log(str1); // '123'
console.log(str2); // '456'
// // 引用數據類型
let arr1 = [1, 2, 3];
arr2 = arr1;
arr2.push(4);
console.log(arr1); // [1, 2, 3, 4]
console.log(arr2); // [1, 2, 3, 4]
我們在例子中可以看到,在直接賦值的情況下,修改finalData也會改變原來的initData,而基本數據類型的拷貝,修改str2不會影響原來的str1,而引用數據類型的拷貝,修改arr2會影響原來的arr1。
那麼這樣就誕生了一個問題,在平時咱們怎麼能進行限次數的拷貝,從而能保證修改拷貝後的數據一直不會影響原來的數據呢?這就是深拷貝的基本概念了。針對以上問題,咱們可以把想法思維化,先寫個小demo,先把各個需要的功能簡單羅列一下。
/**
* @name 賦值
*/
const dataOne = {
title: 'study',
number: ['html', 'css', 'javascript'],
};
const dataTwo = dataOne;
dataTwo.title = 'play';
dataTwo.number = ['null'];
console.log(dataOne);
// dataOne: { title: 'play', number: ['null'] }
console.log(dataTwo);
// dataTwo: { title: 'play', number: ['null'] }
/**
* @name 淺拷貝
*/
const dataThree = {
title: 'study',
number: ['html', 'css', 'javascript'],
};
const dataFour = shallowClone(dataThree); // shallowClone 待實現
dataFour.title = 'play';
dataFour.number = ['null'];
console.log(dataThree);
// dataThree: { title: 'study', number: ['null'] }
console.log(dataFour);
// dataFour: { title: 'play', number: ['null'] }
/**
* @name 深拷貝
*/
const dataFive = {
title: 'study',
number: ['html', 'css', 'javascript'],
};
const dataSix = deepClone(dataFive); // deepClone 待實現
dataSix.title = 'play';
dataSix.number = ['null'];
console.log(dataFive);
// dataFive: { title: 'study', number: ['html', 'css', 'javascript'] }
console.log(dataSix);
// dataSix: { title: 'play', number: ['null'] }
經過上面的實例,就這樣把拷貝分成了三種情況,大致意思就是這樣:
-
賦值:引用地址的拷貝。修改賦值後的數據,不管是基本數據類型還是引用數據類型,都會影響到原數據。
-
淺拷貝:一層拷貝。在淺拷貝中,修改基本數據類型不會影響原有數據的基本數據類型,修改引用數據類型會影響原有的數據類型。
-
深拷貝:無限層級拷貝。在深拷貝中,修改基本數據類型和引用數據類型都不會影響原有的數據類型。
深拷貝與橋拷貝可能在日常開發中都碰不到,但是確是面試常問的問題,雖然碰不到,但是怎麼手寫一個淺拷貝或深拷貝,確是能用到很多知識,還是值得學習的。
下面我的兩篇文章將着重如何寫代碼實現各個拷貝,有興趣的可以看一下。
淺拷貝與深拷貝(二)代碼實現淺拷貝
淺拷貝與深拷貝(三)代碼實現深拷貝
完整文章見: