深度解析javascript中的淺複製和深複製

       在談javascript的淺複製和深複製以前,咱們有必要在來討論下js的數據類型。咱們都知道有Number,Boolean,String,Null,Undefined,Object五種類型。而Object又包含Function,Array和Object自身。前面的五種類型叫作基本類型,而Object是引用類型。可能有人就要問,爲何要分基本類型和引用類型呢?後面你就會明白的。javascript

     咱們首先來看看淺複製和深複製的簡潔定義:java

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

而數據類型和咱們要討論的複製類型又有怎樣的聯繫呢?咱們試着摸索一下吧數組

實驗一:函數

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

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

實驗二:code

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有些不一樣。那些不一樣了?前面的是字符串,後面的數組。好像就是咱們前面提到的基本類型和數據類型吧。那咱們把數據類型換一下看看會有什麼結果。blog

實驗三:ip

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 }

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

相關文章
相關標籤/搜索