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