深拷贝与浅拷贝

50 阅读2分钟

我觉得深拷贝和浅拷贝就是对一个数据类型的操作吧,因为在工作的过程中,

我们经常要去操作一些复杂数据类型,当我们对一个数据类型拷贝出一个副

本来,修改了副本之后,原数据对象发送改变,就是浅拷贝,原来的数据类型不

发生改变,就是深拷贝.其实这个地方就是涉及一个堆栈内存的问题.因为引用

数据类型是存储在堆内存里面的,保存的是一个内存地址的指针指向..浅拷贝

就是指针指向相同.所以修改了其中一个,另一个也是访问的堆内存里面的相

同位置.所以都会发生变换.深拷贝相当于把里面的引用类型,重新在堆内存里

面开辟了一块空间.有了新的一个地址指针的指向.就相互不影响了.项目里面

的时候,我经常使用 JSON.parse(JSON.stringify(深拷贝的对象))的方式来实现

吧.也可以用一个递归的方式.来实现,用的多的话.封装成一个函数,放到

utils.js 中,在引用的地方导入调用.

补充一下引申问题(不用主动回答的):JSON.parse 方式有没有什么缺点. 一般

情况下都没问题.但是你像函数,正则,时间对象,undefined null 拷贝是有问题

的.. 怎么解决?如果包含了一些无法拷贝的情况时,可以使用递归的方式,

就是进去对一些对应的类型做检测. 数组对象重新拓展一份,其它类型都返

回原来的.然后如果值是引用类型,继续递归调用..当时里面还引用了 lodash js

库,直接调用里面的方法.

对象浅拷贝可以理解为改变一个对象属性值,另一个对象属性也会改变,即互相影响

对象深拷贝即就是说改变一个对象属性,另一个对象的属性值不会发生改变

附递归代码:

var china = {
  nation: "中国",
  birthplaces: ["北京", "上海", "广州"],
  skincolr: "yellow",
  friends: ["sk", "ls"],
};
//深复制,要想达到深复制就需要用递归
function deepCopy(o, c) {
  var c = c || {};
  for (var i in o) {
    if (typeof o[i] === "object") {
      //要考虑深复制问题了
      if (o[i].constructor === Array) {
        //这是数组
        c[i] = [];
      } else {
        //这是对象
        c[i] = {};
      }
      deepCopy(o[i], c[i]);
    } else {
      c[i] = o[i];
    }
  }
  return c;
}
var result = { name: "result" };
result = deepCopy(china, result);