深拷贝

182 阅读1分钟

原理:深拷贝 = 浅拷贝 + 递归。在浅拷贝的基础上判断当前属性值是简单类型还是引用类型。如果是简单类型直接赋值,如果是引用类型,递归操作。

function isObject(obj) { // 判断属性值是否为引用类型
	return typeof obj === 'object' && obj != null;
}

function cloneDeep(target, hash = new WeakMap()) {
     if (!isObject(target)) return target;
    const results = Array.isArray(target) ? [] : {}; // 兼容数组类型
    if (hash.has(target)) return hash.get(target); // 解决引用丢失的问题和循环引用的问题
    hash.set(target, results);
    const symkeys = Object.getOwnPropertySymbols(target); // 获取symbol类型的键

    if (symkeys.length) {
        syskeys.forEach(item => { // 拷贝symbol类型属性的值
            if (isObject(target[item])) {
                results[item] = cloneDeep(target[item], hash);
            } else {
                results[item] = target[item]
            }
        })
    }
    for (const k in target) { // 拷贝非Symbol类型属性的值
        if (Object.prototype.hasOwnproperty.call(target, k)) {
            if (isObject(target[k])) {
                results[k] = cloneDeep(target[k], hash);
            } else {
                results[k] = target[k];
            }
        }
    }
    return results;
}