淺拷貝與深拷貝(一)初識

深拷貝和淺拷貝

初識

  js中數據分爲基本數據類型如nullstringundefinednumberbooleansymbol,以及引用數據類型如對象數組

  而在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'] }

經過上面的實例,就這樣把拷貝分成了三種情況,大致意思就是這樣:

  • 賦值:引用地址的拷貝。修改賦值後的數據,不管是基本數據類型還是引用數據類型,都會影響到原數據。

  • 淺拷貝:一層拷貝。在淺拷貝中,修改基本數據類型不會影響原有數據的基本數據類型,修改引用數據類型會影響原有的數據類型。

  • 深拷貝:無限層級拷貝。在深拷貝中,修改基本數據類型和引用數據類型都不會影響原有的數據類型。

  深拷貝與橋拷貝可能在日常開發中都碰不到,但是確是面試常問的問題,雖然碰不到,但是怎麼手寫一個淺拷貝或深拷貝,確是能用到很多知識,還是值得學習的。

  下面我的兩篇文章將着重如何寫代碼實現各個拷貝,有興趣的可以看一下。


淺拷貝與深拷貝(二)代碼實現淺拷貝
淺拷貝與深拷貝(三)代碼實現深拷貝


完整文章見:

自建博客地址:ahuiyo的博客 - 教你手擼深拷貝與淺拷貝

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章