深拷贝和浅拷贝

  • 浅拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function shallowClone(source) {
    if (typeof source !== 'object' || source == null
    {
    return source;
    }
    let target = Array.isArray(source) ? [] : {};
    for (let key in source) {
    //source.hasOwnProperty(key) 判断是否是source自身的属性,不拷贝原型链的属性
    if (source.hasOwnProperty(key)) {
    //shallowClone 实现对属性进行递归拷贝
    target[key] = shallowClone(source[key]);
    }
    }
    return target;
    }
  • 深拷贝(复杂数据类型也会开辟新空间存储)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    // 利用json数据转换来达到深拷贝
    let deePerson = JSON.parse(JSON.stringify(person))

    //或者自己写递归循环实现深拷贝
    function deepClone(obj, hash = new WeakMap()) {
    if (obj == null) return obj; // 如果是null或者undefined我就不进行拷贝操作
    //如果是时间函数Date() 、正则表达式 RegExp()也直接返回
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof RegExp) return new RegExp(obj);
    // 可能是对象或者普通的值 如果是函数的话是不需要深拷贝
    if (typeof obj !== "object") return obj;
    // 是对象的话就要进行深拷贝
    if (hash.get(obj)) return hash.get(obj);
    let cloneObj = new obj.constructor();
    // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
    hash.set(obj, cloneObj);
    for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
    // 实现一个递归拷贝
    cloneObj[key] = deepClone(obj[key], hash);
    }
    }
    return cloneObj;
    }

拷贝弊端:不能拷贝函数 、正则表达式 RegExp()