浅拷贝和深拷贝

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅拷贝和深拷贝相关的知识,希望对你有一定的参考价值。

一、编写框架或者库时,为什么不用原生拷贝方法实现对象拷贝?
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);     // false
console.log(obj2);

 

以上是关于浅拷贝和深拷贝的主要内容,如果未能解决你的问题,请参考以下文章

NumPy之浅拷贝和深拷贝

C#的浅拷贝和深拷贝

js 对象的浅拷贝和深拷贝

python中的浅拷贝和深拷贝

JS-[浅拷贝和深拷贝]

js的浅拷贝和深拷贝