数组和对象的浅拷贝和深拷贝

在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;
}
原文地址:https://www.cnblogs.com/shenjp/p/6950040.html