JS中的深拷贝vs浅拷贝

未标题-1 拷贝.jpg

我们知道,JS 中的数据分为基础数据类型 (Undefined, Null, Boolean, Number, String, symbol) 和引用数据类型(object)。
当赋值给变量进行数据保存时,前者保存的是数据实体,后者保存的是数据实体在堆内存中的地址
为什么会这样?在 JS 中,也有栈内存堆内存的概念。
,是在程序编译时分配,它是连续的内存空间,容量小,系统分配效率高,有后进先出的特性,适合存储简单有固定尺寸的数据,如基础数据。
,是在程序运行时申请的某个大小的内存空间,不连续,树形结构。容量大,系统分配效率略低,适合存储尺寸不确定的数据,如 Object。
基础数据的存储是系统直接在栈内存中开出一块空间存值,而 Object 的存储,是先在堆内存中开辟空间存值,然后在栈内存中存址。

本质区别

深拷贝和浅拷贝的本质区别在于对引用类型数据的拷贝,前者拷值,后者拷址。

本文所述的拷贝主要是对象和数组的拷贝。

代码实现

// data type
const whatType = obj => Object.prototype.toString.call(obj).slice(8, -1)

// shallow copy
function shallowCopy(obj) {
  let result;
  switch (whatType(obj)) {
    case "object":
      result = {};
      break;
    case "Array":
      result = [];
      break;
    default:
      return obj
  }

  for (key in obj) {
    obj[key] = obj[key]
  }

  return result
}

// deep copy
const deepCopy = (function f(obj) {
  let result;
  switch (whatType(obj)) {
    case "Object":
      result = {};
      break;
    case "Array":
      result = [];
      break;
    default:
      return obj
  }

  for (key in obj) {
    const type = whatType(obj[key])
    if ( type=== "Object" || type === "Array") {
       result[key] = f(obj[key])
    } else {
      result[key] = obj[key]
    }
  }
  
  return result
})

// 深拷贝的另一种简便方式
const deepCopy2 = obj => JSON.parse(JSON.stringfy(obj))

推荐阅读更多精彩内容