深浅拷贝

102 阅读2分钟

区别

深拷贝和浅拷贝最根本的区别在于是否真正获取一个对象的复制实体,而不是引用。

浅拷贝(shallowCopy)只是增加了一个指针指向已存在的内存地址,

深拷贝(deepCopy)是增加了一个指针并且申请了一个新的内存,使这个增加的指针指向这个新的内存

比较完整的方法

//深拷贝功能函数
function deepClone(obj, hash = new WeakMap()) {
    //判断是null或undefined直接返回
    if (obj == null) return obj;
    //number string boolean symbol 等基本类型直接返回
    if (typeof obj !== 'object') return obj;//是对象类型继续往下
    //object
    //判断是日期,new一个日期并返回
    if (obj instanceof Date) return new Date(obj);
    //判断是正则,new一个正则并返回
    if (obj instanceof RegExp) return new RegExp(obj);
    if (hash.get(obj)) {
        return hash.get(obj);
    }
    //数组 空对象{}
    let newObj = new obj.constructor;
    hash.set(obj, newObj);
    for (let key in obj) {
        // obj无论是数组还是对象 都可以进行for in迭代
        newObj[key] = deepClone(obj[key], hash);
    }
    return newObj;
}
//函数使用
let arr = [1, 2, 3, { a: 1, b: [1, 5] }];
console.log(deepClone(arr));//[1, 2, 3, { a: 1, b: [1, 5] }]

一,对象深拷贝的3种方法

1. 使用递归的方式实现深拷贝
function deepClone(obj){
  let objClone =  Array.isArray(obj) ? [] : {};
  if (obj && typeof obj === 'object') {
    for(let key in obj){
      if (obj[key] && typeof obj[key] === 'object'){
        objClone[key] = deepClone(obj[key]);
      }else{
        objClone[key] = obj[key]
      }
    }
  }
  return objClone;
}
2. 通过JSON对象实现深拷贝
function deepClone2(obj) {
  let _obj = JSON.stringify(obj),
  return JSON.parse(_obj);
}

注意: 无法实现对象中方法的深拷贝:

image.png

3. 通过Object.assign()拷贝

注意: 当对象只有一级属性为深拷贝;

当对象中有多级属性时,二级属性后就是浅拷贝

image.png

二,数组深拷贝的2种方法

1. concat(arr1, arr2,....)

注意:当数组中的元素均为一维是深拷贝,数组中元素一维以上是值的引用

image.png

2. slice(idx1, idx2)

参数可以省略

1)没有参数是拷贝数组

2)只有一个参数是从该位置起到结束拷贝数组元素

3)两个参数,拷贝从起始位置到结束位置的元素(不包含结束位置的元素:含头不含尾)

注意:当数组中的元素均为一维是深拷贝,数组中元素一维以上是值的引用

image.png