js关于数据深度复制

142 阅读1分钟
最近翻看es6的语法正好看到对象扩展符...和Object.assign都是可以复制数据,但是都是浅层复制值

由此想怎么才能做到深层复制呢?
在此之前我们复习下数据存储的问题,首先基本类型的数据是存储在栈内存中,对应的就是该变量的值。
而引用数据类型栈中存的是堆内存的指针。那么我们只要将复制其堆内存中存取的数据并赋值给新的变量即可
那么开始实现代码

整体思路是写两个函数分别处理复制的数据是object和array,然后再用一个函数总得执行copy数据

### 1.第一步写复制的数据类型为object
<pre>
  function copyDeepObj(copyObj) {
    const newObj = {};
    for(var key in copyObj) {
    const item = copyObj[key];
    const isArray = Object.prototype.toString.call(item).includes('Array');
    const isObject = Object.prototype.toString.call(item).includes('Object');
    if(isObject) {
      newObj[key] = arguments.callee(item);
    } else if(isArray) {
      newObj[key] = copyDeepArray(item)
    }else {
      newObj[key] = item;
    }
    }
    return newObj;
    }
</pre>
### 2.第二步写复制的数据类型为array
<pre>
function copyDeepArray(copyArr) {
  const newArray = [];
  for(var item of copyArr) {
    const isObject = Object.prototype.toString.call(item).includes('Object');
    const isArray = Object.prototype.toString.call(item).includes('Array');
    if(isObject) {
      newArray.push(copyDeepObj(item));
    } else if(isArray) {
      newArray.push(arguments.callee(item))
    } else {
      newArray.push(item)
    }
  }
  return newArray;
}
</pre>
### 3.第三步调用函数生成最终复制数据
<pre>
  function copyData(copydata) {
  const isObject = Object.prototype.toString.call(copydata).includes('Object');
  const isArray = Object.prototype.toString.call(copydata).includes('Array');
  if(isObject){
    return copyDeepObj(copydata)
  } else if(isArray) {
    return copyDeepArray(copyData)
  }
  return copydata;
}
</pre>
### 接下来我们测试下代码
<pre>
  const a = {
  a: 'name',
  b: 1,
  c: true,
  d: { e: 1, c: {f: 2}, g: [12, 3] },
  f: [{a: 23}, 2, true, [23,3,3]]
  }
  const b = copyData(a);
  b.d.g.push('new');
  此时a.d.g的值为[12,3]说明深度拷贝成功
</pre>