在jsvaScript中,簡單值是通過直復制來進行賦值傳遞的,而引用類型是通過引用賦值來進行復制傳遞的。
var a = 2; var b = a; b = 3; console.log(a) //2 console.log(b) //3 var arr1 = [1,2,3]; var arr2 = arr1; arr2.push(4); console.log(arr1); //[1,2,3,4] console.log(arr2); //[1,2,3,4]
第一種情況就是簡單值得復制傳遞,a和b分別在兩個內存中,b=a知識吧a的值復制給b,改變b的值不會影響a的值。
第二種情況是引用類型的復制,arr2 = arr1是將arr1的地址復制給arr2,兩個數組指向同一片內存區域,所以改變arr2的值也會改變arr1的值。是數組的淺拷貝。
下面來看看什么是數組的深拷貝
var a = [1,2,3]; var b = a.slice(0); var c = a.concat(); b.push(4); c.push(5); console.log(a); //[1,2,3] console.log(b); //[1,2,3,4] console.log(c); //[1,2,3,5]
對象的淺拷貝
function easyClone(Obj) { var objNew = {}; for ( var i in Obj) { objNew[i] = Obj[i]; } return objNew; }
其實就是將每個原對象的屬性和值復制到新對象上去,當然我們也可以使用Object.assign() 方法可以把任意多個的源對象自身的可枚舉屬性拷貝給目標對象,然后返回目標對象,同時Object.assign() 也是淺拷貝。
淺拷貝因為沒有遞歸循環檢查對象的每個值是否是對象,而是直接進行了賦值,所以如果某個值是對象的時候就會出現問題,所以在一般情況下我們需要用深拷貝來進行備份。
對象的深拷貝
最簡單的深拷貝
var b = JSON.parse(JSON.stringify(a))
但是這種深拷貝有一定的局限性,第一:無法復制函數,第二:原形鏈沒了,對象就是object,所屬的類沒了。
其實簡單的深拷貝只需要我們遞歸調用淺拷貝就可以了:
function deepCopy(obj) { var objNew = objNew || {}; for (var i in obj) { if (typeof p[i] === 'object') { objNew[i] = (p[i].constructor === Array) ? [] : {}; deepCopy(obj[i], objNew[i]); } else { objNew[i] = obj[i]; } } return objNew; }