共勉~編程
在許多編程語言中,傳遞參數和賦值是經過值的直接複製或者引用複製完成的。在JavaScript中,對於值是直接進行復制仍是引用複製在語法上是沒有區別的,徹底是根據值的類型來決定的。數組
在JavaScript中,簡單值老是經過值的直接複製來進行賦值傳遞的(null,undefined,字符串,數字,布爾,symbol),而複合值(對象(包括數組等)和函數)老是經過引用複製的方式來進行賦值和傳遞的。編程語言
下面的例子能加深理解:函數
var a = 1; var b = a; b++; a; //1 b; //2 var c = [1,2]; var d = c; d.push(3); c; //[1,2,3] d; //[1,2,3]
上面例子對於數組的賦值操做就是數組的淺拷貝,不難發現問題當一個數組改變的時候,其餘賦值的數組也會改變,在不少相似備份的狀況中,這並非咱們想要的結果。spa
var c = [1,2]; var d = c; d.push(3); c; //[1,2,3] d; //[1,2,3]
咱們能夠經過兩種方法來實現數組的深拷貝:code
var a = [1,2,3]; var b = a.slice(0); var c = a.concat(); b.push(4); c.push(5); a; //[1,2,3] b; //[1,2,3,4] 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() 也是淺拷貝,有興趣的同窗能夠看看。blog
淺拷貝由於沒有遞歸循環檢查對象的每一個值是不是對象,而是直接進行了賦值,因此若是某個值是對象的時候就會出現問題,因此在通常狀況下咱們須要用深拷貝來進行備份。遞歸
最簡單的深拷貝:ip
b = JSON.parse( JSON.stringify(a) )
侷限性:
其實簡單的深拷貝只須要咱們遞歸調用淺拷貝就能夠了:
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; }
固然JQ的jQuery.extend()方法也能夠作到深拷貝和淺拷貝:詳情能夠參考這篇文章: