深拷贝与浅拷贝

357 阅读1分钟

平时我们在做开发时,由于对象和数组都是引用类型。所以不能直接用“=”来复制一个对象 开发中我们用的比较多的浅拷贝复制或者数组的方法就是扩展符

浅拷贝复制对象或者数组

let a={name:'111'};
复制对象a
我们可以用
let b = {...a}
数组也是这个道理
let c=[1,2,3]
let d=[...c];

深拷贝复制一个对象

let a={name:'111',props:{age:21,height:180}}
复制对象a
let b = JSON.parse(JSON.stringify(a));

但是它还是有很大缺陷的,比如拷贝其他引用类型、拷贝函数、循环引用等情况。

我们可以写一个简单的函数

浅拷贝函数

function clone(target) {

        let cloneTarget = {};

        for (const key in target) {

            cloneTarget[key] = target[key];

        }

        return cloneTarget;

    };

深拷贝函数

function isObject(obj) {
  return typeof obj === 'object' && obj != null;
}
function deepCopy(source, hash = new WeakMap()) {
        // 判断如果参数不是一个对象,返回该参数
        if (!isObject(source)) return source;
        if (hash.has(source)) return hash.get(source); // 如果拷贝过该对象,则直接返回该对象
        // 判断参数是对象还是数组来初始化返回值
        let res = Array.isArray(source) ? [] : {};
        hash.set(source, res); // 哈希表添加新对象
        // 循环参数对象的key
        for (let key in source) {
            // 如果该key属于参数对象本身
            if (Object.prototype.hasOwnProperty.call(source, key)) {
                // 如果该key的value值是对象,递归调用深拷贝方法进行拷贝
                if (isObject(source[key])) {
                    res[key] = deepCopy(source[key], hash);
                } else {
                    // 如果该key的value值不是对象,则把参数对象key的value值赋给返回值的key
                    res[key] = source[key];
                }
            }
        }
        // 返回返回值
        return res;
    };