理解浅拷贝和深拷贝

215 阅读1分钟
  • 浅拷贝, 是指创建一个对象,这个对象有着原始对象属性值的一份精确拷贝,如果属性是基本类型,那么拷贝的就是基本类型的值。 如果属性是应用类型,那么拷贝的是内存地址,如果其中一个对象修改了某些属性,另外一个对象也会改变。
  • 深拷贝,是指从一个内存中完整的拷贝一个对象出来,并且在堆内存中为其分配一个新的内存区域来存放。并且修改该对象属性值,不会影响到原来的对象。

浅拷贝的方式: 对象扩展运算符(...、 ==) 、 数组的slice方法、数组的concat

深拷贝的方式: 通过 JSON.Stringify 和 JSON.parse 方式来转换,还有用原生JS 手动递归来实现。


// 元素类型判断
const getType = obj => {
  // tostring会返回对应不同的标签的构造函数
  const { toString } = Object.prototype;
  const map = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object',
  };
  if (obj instanceof Element) {
    return 'element';
  }
  return map[toString.call(obj)];
};

// 深拷贝方法
export const deepClone = data => {
  const type = getType(data);
  let obj;
  if (type === 'array') {
    obj = [];
  } else if (type === 'object') {
    obj = {};
  } else {
    // 不再具有下一层次
    return data;
  }
  if (type === 'array') {
    for (let i = 0, len = data.length; i < len; i += 1) {
      obj.push(deepClone(data[i]));
    }
  } else if (type === 'object') {
    Object.keys(data).map(d => {
      obj[d] = deepClone(data[d]);
      return d;
    });
  }
  return obj;
};