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


在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;
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM