今天學到了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; }
這樣就能將所有的數據都拷貝到另一個儲存空間里。
