SOURCE

const is = (function (){
    function call(target, flag) {
        return Object.prototype.toString.call(target) === flag;
    }
    return {
        number: num => call(num, '[object Number]'),
        string: str => call(str, '[object String]'),
        func: func => call(func, '[object Function]'),
        arr: arr => call(arr, '[object Array]'),
        obj: obj => call(obj, '[object Object]')
    }
})()


function copy(target, isDeep = false) {
    if(!(is.arr(target) || is.obj(target))) {
        throw Error('target 必须是一个数组或者对象');
    }
    const keys = Object.keys(target);
    let ret = is.arr(target) ? [] : {};

    for(let i = 0, l = keys.length; i < l; i++){
        let key = keys[i];
        let val = target[key];
        
        if((is.arr(val) || is.obj(val)) && isDeep) {
            ret[key] = copy(val, isDeep);
        } else {
            ret[key] = val;
        }
    }
    return ret;
}

let a = {a: 1, b: {c: {d:4}}}
let b = copy(a,true);
a.b.c = 'a';
console.log(a,b)

let aa = [1,[2,[3]],{a:1}]
let bb = copy(aa,true);
aa[1][0] = 'a';
console.log(aa,bb)
console 命令行工具 X clear

                    
>
console