深度解析javascript中的淺復制和深復制


       在談javascript的淺復制和深復制之前,我們有必要在來討論下js的數據類型。我們都知道有Number,Boolean,String,Null,Undefined,Object五種類型。而Object又包含Function,Array和Object自身。前面的五種類型叫做基本類型,而Object是引用類型。可能有人就要問,為什么要分基本類型和引用類型呢?后面你就會明白的。

     我們首先來看看淺復制和深復制的簡潔定義:

  • 深復制:直接將數據復制給對應的變量
  • 淺復制:將數據的地址復制給對應的變量

而數據類型和我們要討論的復制類型又有怎樣的聯系呢?我們試着摸索一下吧

實驗一:

1 var a = "dengkunming";
2 var a1 = a;
3 alert(a1);//dengkunming
4 a="abc";
5 alert(a1);//dengkunming;

這段代碼中我們把a賦值給a1,當a的值改變時,a1沒有發生變化。

實驗二:

1 var a = [0,1,2,3];
2 var a1= a;
3 alert(a1);//[0,1,2,3]
4 a[1]="變";
5 alert(a1);//[0,"變",2,3]

在這段代碼中我們同樣把a賦值給a1,當a的值改變的時候,a1卻發生了變化。

     這是咋回事了,同樣的操作其結果怎么會有差異了?我們回頭看看,聰明的一休認為可能是這兩個a有些不同。那些不同了?前面的是字符串,后面的數組。好像就是我們前面提到的基本類型和數據類型吧。那我們把數據類型換一下看看會有什么結果。

實驗三:

1 var a = 3578;
2 var a1 = a;
3 alert(a1);//3578
4 a=8735;
5 alert(a1);//3578

實驗四:

1 1 var a = {w1:2,w2:3}
2 2 var a1= a;
3 3 alert(a1);//{w1:2,w2:3}
4 4 a1.w1="鄧";
5 5 alert(a);//{w1:"鄧",w2:3}

    在這兩組實驗中,我們把數據類型分別換成了Number型和Object類型。實驗三中可以發現a1不隨a值的變化而變化,實驗四中a會隨着a1的變化而變化(這里和實驗二略有不同,改變的是a1,當然你改變a的話,a1也會跟着變化)

   似乎我們可以得出個一般性的結論了:

    js中基本類型的賦值為深復制,而引用類型的賦值為淺復制。

   現在有必要把深復制和淺復制的定義擴展一下了。

  • 淺復制:就是把數據的地址賦值給對應變量,而沒有把具體的數據復制給變量,變量會隨數據值的變化而變化。
  • 深復制:就是把數據賦值給對應的變量,從而產生一個與源數據不相干的新數據(數據地址已變化)。

實驗五:

1 var a = {w1:2,w2:3}
2 var a1= a;
3 alert(a1);//{w1:2,w2:3}
4 var a={x1:7,x2:8}
5 alert(a1);//{w1:2,w2:3}

     按照我們上面的理論來講,這里是淺復制。a1應該隨着a的變化而變化呀,可在這里為什么會事與願違了?這就是引用類型惹的禍了。對象賦值其實都是引用傳值,傳遞的是一個地址。那么實驗五中的第四行其實就是把變量a指向了一個新的地址。而a1還是指向的原來那個地址,原來地址中的值沒變,所以a1就不會變。所以請記住:淺復制不會隨着存儲數據地址的變化而變化,只會隨着數據值的變化而變化。

     那我們如何實現引用類型的深度復制呢?這就是老話題深度克隆了。就是需要自己寫一個非原生的clone函數嘍。

 1 function clone(obj){
 2     var o=[]; 
 3     if(obj.constructor== Array) {
 4         o=obj.slice(0);
 5        }else{
 6            o={};
 7            for(var i in obj){
 8                 o[i] = typeof obj[i] === "object" ? obj[i].clone() : obj[i];} 
 9        }
10        return o;
11 
12 }

    小可不才,文章中定會有所紕漏,望指出。也學一下大牛的語氣,此文原創,轉載請注明出處。如果你覺得文章還不錯,就怒頂並推薦一下下吧!!!!


免責聲明!

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



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