1. 程式人生 > 實用技巧 >深拷貝和淺拷貝原理

深拷貝和淺拷貝原理

基礎資料型別:

  string、number、null、undefined、boolean、symbol

引用資料型別:

  函式、物件、陣列

產生原因:

  基本型別是按值訪問的,引用型別是按引用訪問

  1、基本型別的儲存是放在棧區的

  2、引用型別的儲存是放在堆記憶體中的

  當引用型別進行賦值的時候,JavaScript不允許直接訪問記憶體中的位置,也不能直接操作物件中的記憶體空間。操作物件是直接操作物件的引用,而不是整個物件,所以就會出現深拷貝、淺拷貝的問題

  淺拷貝只複製指向某個物件的指標,而不復制物件本身,相當於是新建了一個物件,該物件複製了原物件的指標,新舊物件還是共用一個記憶體塊,

  深拷貝是新建一個一模一樣的物件,該物件與原物件不共享記憶體,修改新物件也不會影響原物件

淺拷貝實現方式:

  1、物件使用Object.assign(target, source)方法

     let  testDeepObj2 =   Object.assign({},testDeepObj1);

  testDeepObj1物件中有引用型別的話,就是淺拷貝

  2、陣列使用slice()、concat()方法

        var arr = ['jack',25,{hobby:'tennise'}];
        let arr1 = arr.slice()
        arr1[2].hobby='rose'
        arr1[0]='rose'
        console.log( arr[2].hobby) //rose
        console.log( arr[0]) //jack    

  

深拷貝實現方式:

  1.JSON.parse(JSON.stringify()),這種方式的缺點是當物件裡面有函式的話,深拷貝後,函式會消失

     let arr1 = JSON.parse(JSON.stringify(arr))

  2、手寫遞迴函式實現深拷貝

function copy(obj){
        let newobj = null;   //宣告一個變數用來儲存拷貝之後的內容
        
     //判斷資料型別是否是複雜型別,如果是則呼叫自己,再次迴圈,如果不是,直接賦值即可,
     //由於null不可以迴圈但型別又是object,所以這個需要對null進行判斷
        if(typeof(obj) == 'object' && obj !== null){ 
        
	//宣告一個變數用以儲存拷貝出來的值,根據引數的具體資料型別宣告不同的型別來儲存
            newobj = obj instanceof Array? [] : {};   
            
	//迴圈obj 中的每一項,如果裡面還有複雜資料型別,則直接利用遞迴再次呼叫copy函式
            for(var i in obj){  
                newobj[i] = copy(obj[i])
            }
        }else{
            newobj = obj
        }    
        console.log('77',newobj)
      return newobj;    //函式必須有返回值,否則結構為undefined
   }

  

參考文獻:https://blog.csdn.net/qq_34645412/article/details/106327826