前端深拷貝和淺拷貝的原理及應用

1.1 數據類型對拷貝的作用

1.11 數據類型:

(1)基礎數據類型(primitive data types):

基礎數據類型:簡單的數據端,基礎類型的數據有Number,Null,Boolean,Number and String。這五種基礎類型可以按值訪問,可以直接操作保存在變量的實際值(文字來源:JavaScript高級程序設計)

在這裏插入圖片描述


 let test1 = "123";
   let test2 = test1;
   window.console.log("變化之前")
   window.console.log(`test1-${test1}`)
   window.console.log(`test2-${test2}`)
 
   test2 = "321";
   window.console.log("變化之後");
  window.console.log(`test2-${test2}`)
  window.console.log(`test1-${test1}`)



在這裏插入圖片描述

(2)引用數據類型(Composite data types):

引用數據類型數據是指那些可能多個值構成的對象,有Array,Object等,引用類型值保存在堆內存中,JavaScript不允許直接訪問內存中的位置,也不能直接操作對象的內存空間。操作對象時是直接操作對象的引用,而不是真正對象,所以會有深拷貝和淺拷貝的問題 (文字來源:JavaScript高級程序設計)

在這裏插入圖片描述

2.1 淺拷貝

淺拷貝賦值的變量,會同時指向同一個棧內存地址下的值,會影響所以變量下的賦值
在這裏插入圖片描述


  //引用數據類型,只能拿到內存裏面的引用
  let testObj1 = {
      name:"testObject"
  }
  let testObj2 = testObj1
  window.console.log("變化之前前");
  window.console.log("testObj1");
  window.console.log(testObj1)
  window.console.log("testObj2");
  window.console.log(testObj1)
  testObj2.name = "testObj2";
  window.console.log("變化之後");
  window.console.log("testObj1");
  window.console.log(testObj1)
  window.console.log("testObj2");
  window.console.log(testObj1)



在這裏插入圖片描述

3.1 深度拷貝

深拷貝不會拷貝引用類型的引用,而是將引用類型的值全部拷貝一份,形成一個新的引用類型,這樣就不會發生引用錯亂的問題,使得我們可以多次使用同樣的數據,而不用擔心數據之間會起衝突
在這裏插入圖片描述

3.2 使用方法:

3.21 方案一:使用Object.assign(target, source)方法

 let  testDeepObj1 = {
    name:"testDeepObject"
}
let  testDeepObj2 =   Object.assign({},testDeepObj1);
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


在這裏插入圖片描述

3.22 方案二:使用ES6{…}

 let  testDeepObj1 = {
    name:"testDeepObject"
}
let  testDeepObj2 = {...testDeepObj1};
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


3.23 方案三:把賦值的值先利用JSON.stringfy()字符串化然後複製的時候在轉爲JSON.parse()

let  testDeepObj1 = JSON.stringify({
    name:"testDeepObject"
})
let  testDeepObj2 = JSON.parse(testDeepObj1);
window.console.log("變化前")
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);
testDeepObj2.name = "111"
window.console.log("變化後");
window.console.log("testDeepObj1");
window.console.log(testDeepObj1);
window.console.log("testDeepObj2");
window.console.log(testDeepObj2);


x.1 參考材料:

(1) 淺談JS深拷貝(深克隆)@郝晨光 :

https://www.jianshu.com/p/f4329eb1bace

(2)JavaScript高級程序設計
(3)How to differentiate between deep and shallow copies in JavaScript

https://www.freecodecamp.org/news/copying-stuff-in-javascript-how-to-differentiate-between-deep-and-shallow-copies-b6d8c1ef09cd/

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