JavaScript的一個深拷貝的例子——遞歸函數的實現


  今天學到了JS的關於深拷貝和淺拷貝的例子,有些體會。

  在JavaScript中,變量的拷貝分為兩種,一種是值拷貝,一種是內存地址拷貝,意思是當賦值給變量的只是一個簡單的基本數值時,變量與變量之間的儲存空間是相互獨立,兩個變量之間的改變不會相互影響,而當賦值給變量的是一個對象或數組的時候,變量與變量之間的存儲空間將會指向同一個內存空間,當某一個變量改變時,內存空間的值也會改變。

//值拷貝
var i = 4;
var j = i;
//內存地址拷貝
var m = {name:'xxx'};
var n = m;

 

淺拷貝,只是簡單的變量賦值,如果賦值的變量是引用類型的對象,變量之間會共享一個內存空間,每個變量的修改都會影響內存空間里的值;深拷貝,也就是實現將引用類型的數據值拷貝到另一個新創建的儲存空間里。

//淺拷貝
var obj1 = {name = 'xxx'};
var obj2 = obj1;//指向同一個內存地址
//深拷貝
var obj1 = {name = 'xxx'};
var obj2 = {};//創建一個新空間
obj2.name = obj1.name;//存放name的數值

這是一個比較簡單的對象的拷貝,再來看一個比較復雜的:

var people = {
         name:'xxx',                                                  //基本數值
         friends:['people1','people2','peopple3'],           //數組
         info:{                                                           //對象
               phone:'133xxxxxxxx',
               age:'18',
               sex:'man'
         }   
}
        

如果這種復雜的對象只是簡單的賦值給另一個變量的,那就是淺拷貝,這樣我們會遇到一些問題:

var man1 = people;
var man2 = people;
man1.name = '李四'; //man2的名字也變成李四 man1.friends[
0] = '張三';//man2的第一個朋友也變成了'張三' man1.info.age = '20';//man2的年齡也變成了20

所以我們需要將每個數組和變量都進行復制。我們可以封裝一個函數,用來深拷貝:

function(obj,copy){
         for(var i in obj){
               copy[i] = obj[i];//復制obj中的每一個項
         }
         return copy;
}

這樣寫還是有問題就是當obj中的某個屬性任然是引用類型的變量時,依然會指向同一個內存空間。所以我們就可以用遞歸的方法,讓是對象的屬性再通過遍歷來賦值。

function deepCopy(obj,copy){
           for(var i in obj){
                     if(typeOf obj[i] == 'object'){       //判斷是否為對象
                               deepCopy(obj[i],copy[i]);//回調深拷貝函數
                     }
                     else{
                               copy[i] = obj[i];             //不是對象直接復制
                     }
           }  
           return copy; 
}                                                                                    

這樣就能將所有的數據都拷貝到另一個儲存空間里。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM