浅拷贝:只拷贝数组或者对象的引用,无论在新的或者旧的数组或者对象中作了修改,两者都会发生变化,即两个指向的地址是同一块。

深拷贝:这种拷贝使两者分离,修改一个对象的属性,另外一个也不会有影响,即深拷贝会把所有东西重新复制一份放在另一个地方,两者指向的不是同一块地址。

1. JSON.stringify() &JSON.parse()

将JSON.stringify对象转换成字符串,然后通过JSON.parse将字符串转换成对象

var obj = {a:1, b:2, c:3};
var obj2 = JSON.parse(JSON.stringify(obj));
obj2.a = 2;
console.log(obj.a);
console.log(obj2.a);

上面的结果输出分别是:1和2

说明obj 和 obj2之间没有关系了,实现深拷贝

缺点:只能用于对象属性的深拷贝不能用于对象方法的拷贝

var arr = [function(){
    console.log(a)
}, {
    b: function(){
        console.log(b)
    }
}]

var new_arr = JSON.parse(JSON.stringify(arr));

console.log(new_arr);

 输出结果:

 

2. Object.assign(),可以实现对象属性和方法的深拷贝

实现对象属性的深拷贝

const object1 = {
  a: 1,
  b: 2,
  c: 3
};

const object2 = Object.assign({}, object1);

object2.a = 2;

console.log(object1);
console.log(object2);

实现对象方法的深拷贝

const object1 = {
  a: 1,
  b: 2,
  c: function() {console.log('hello')}
};

const object2 = Object.assign({}, object1);

object2.c = function() {
  console.log('test');
}

console.log(object1.c());
console.log(object2.c());

输出结果分别是:'hello'和'test'

以上两个方法都可以实现对象深拷贝,但是各自的使用是有限制的,可以根据需求使用。

3. 用js方法实现深拷贝

function deepClone(source, target) {
  var target = target || {},
      toStr = Object.prototype.toString, //
      arrType = '[object Array]';
  for(key in source) {
    if(typeof(source[key]) === 'object' && source[key] !== null) {
      if(toStr.call(source[key]) === arrType) { //判断一个对象是否是数组
        target[key] = [];
      } else {
        target[key] = {};
      }

      deepClone(source[key], target[key]); //对象或者数组中还有数组则用递归调用
    } else {
      target[key] = source[key];
    }
  }

  return target;
}


var sour = {
  a: '1',
  b: {
    aa: 1,
    bb: [1, 2],
    cc: {
      xx: 1,
      yy: [{a: 1}]
    }
  }
};

var tar = deepClone(sour);
tar.b.cc.xx = 2;
tar.b.cc.yy.push({b:2});
console.log(tar);
console.log(sour);

 

posted on 2018-10-25 17:56  yyy_鸳鸯  阅读(181)  评论(0编辑  收藏  举报