JS數組和對象的淺拷貝和深拷貝

共勉~編程

在許多編程語言中,傳遞參數和賦值是經過值的直接複製或者引用複製完成的。在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) )

侷限性:

  • 沒法複製函數
  • 原型鏈沒了,對象就是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;
}

 

固然JQ的jQuery.extend()方法也能夠作到深拷貝和淺拷貝:詳情能夠參考這篇文章:

淺拷貝深拷貝之jQuery中的$.extend分析

相關文章
相關標籤/搜索