首页 > 代码库 > 浅拷贝和深拷贝

浅拷贝和深拷贝

一、编写框架或者库时,为什么不用原生拷贝方法实现对象拷贝?
1、Object.assign, Object.create, Object.clone,性能低下;
2、Object.assign在IE系列浏览器全军覆没,兼容性不好;
3、对于已经执行了Object.freeze的对象,Object.create拷贝无效;
4、Object.clone在Chrome中完全不支持,兼容性不好。

二、浅拷贝
只能拷贝基本类型的数据,对于引用类型,只会拷贝引用地址。两个拷贝对象共用同一个引用类型,会相互影响。

1、小技巧
假如有这样一个数组,let arr = [1,‘a‘,true,null,undefined];

//A、slice()方法let sc = arr.slice();  //复制了引用,看起来像深拷贝//B、concat()方法let cc = arr.concat();  //复制了引用,看起来像深拷贝//C、from()方法let fc = Array.from(arr);//D、push()方法let pc = [];Array.prototype.push.apply(pc,arr);//E、map()方法let mc = arr.map(function(item){  return item;});

2、对象或数组的浅拷贝

function shallowCopy(parent, child){  var i, nobj = child || {};  for(i in parent){    parent.hasOwnProperty(i) && (nobj[i] = parent[i]);  }  return nobj;}var obj1 = {  a: 1,  b: { f: { g: 1 } },  c: [ 1, 2, 3 ]};var obj2 = shallowCopy(obj1);console.log(obj2.b.f === obj1.b.f);   //true

3、Object.assign()
把任意多个的源对象自身的可枚举属性拷贝给目标对象,然后返回目标对象。

var obj1 = {  a: 1,  b: { f: { g: 1 } },  c: [ 1, 2, 3 ]};var obj2 = Object.assign({}, obj1);console.log(obj2.b.f === obj1.b.f);   //true

三、深拷贝
可以拷贝引用类型数据,比如数组,对象。实现原理是,递归调用"浅拷贝"。两个拷贝对象共用同一个引用类型,互不影响。

1、JSON的方式浅层次序列化对象

假如有这样一个数组,let arr = [1,2,true,3,‘a‘];let jsonc = JSON.parse(JSON.stringify(arr));

“浅层次”意味着正则表达式类型、函数类型等无法进行深拷贝。

2、对象或数组的深拷贝

function deepCopy(parent, child){  var i, nobj = child || {};  for(i in parent){    if(parent.hasOwnProperty(i)){      if(typeof parent[i]===‘object‘){        nobj[i] = Array.isArray(parent[i]) ? []:{};        deepCopy(parent[i], nobj[i]);      }else{        nobj[i] = parent[i];      }    }  }  return nobj;}var obj1 = {  a: 1,  b: { f: { g: 1 } },  c: [ 1, 2, 3 ],  d: function(value){    this.e = value;  }};var obj2 = deepCopy(obj1);console.log(obj2.b.f === obj1.b.f);     // falseconsole.log(obj2);

 

浅拷贝和深拷贝