SOURCE

function shadowCopy(obj) {
    if (typeof obj !== 'function' && typeof obj !== 'object') {
        return obj;
    }
    let fake = Array.isArray(obj) ? [] : {};
    for (let i in obj) {
        fake[i] = obj[i];
    }

    return fake;
}

// 扩展:Object.assign()

const originalData = { a: 1, b: { c: 2}};

const fakeShadowData = shadowCopy(originalData);

// fakeData.a = 2;
// fakeData.b.c = 4;

// console.log('fakeData', fakeData);
// console.log('originalData', originalData);

function isObject(obj) {
    return typeof obj === 'function' || typeof obj === 'object';
}

// function deepClone(obj) {
//     if (!isObject(obj)) {
//         return obj;
//     }
//     let fake = Array.isArray(obj) ? [] : {};
//     for (let i in obj) {
//         if (isObject(obj[i])) {
//             fake[i] = deepClone(obj[i]);
//         } else {
//             fake[i] = obj[i];
//         }
//     }

//     return fake;
// }

// 拓展:lodash中cloneDeep、JSON.stringify(注意:这个无法拷贝方法)
// 上述遍历实际也是为了拿到key去遍历,Reflect.ownKeys(obj)返回的也是key数组,上面的拷贝无法解决循环引用的情况

function deepClone(obj, map = new Map()) {
    if (typeof obj === 'object') {
        let clone = Array.isArray(obj) ? [] : {};
        if(map.get(obj)) {
            return map.get(obj);
        }
        for(let i in obj) {
            clone[i] = deepClone(clone[i], map);
        }
        return clone;
    } else {
        return obj;
    }
}

let fakeDeepData = deepClone(originalData);

fakeDeepData.a = 2;
fakeDeepData.b.c = 4;

console.log('fakeDeepData', fakeDeepData);
console.log('originalData', originalData);
console 命令行工具 X clear

                    
>
console