实现一个简单的js深拷贝

197 阅读1分钟
class DeepClone{
    constructor() {
        this.cacheList = [];
    }
    // 如果有环就用这个函数
    findCache(source) {
        for(let i = 0; i < this.cacheList.length; i ++) {
            if (source === this.cacheList[i][0]) { return this.cacheList[i][1]; }
        }
        return undefined;
    }
    clone(source) {
        if (!(source instanceof Object)) { return source; }
        const cache = this.findCache(source);
        if (cache) { return cache; }

        let target = {};
        if (source instanceof Array) {
            target = new Array;
        } else if (source instanceof Function) {
            target = function (...args) { return source.apply(this, args); }
        } else if (source instanceof RegExp) {
            target = new RegExp(source.source, source.flags);
        } else if (source instanceof Date) {
            target = new Date(source);
        }
        this.cacheList.push(source, target);

        for (let key in source) {
            if (source.hasOwnProperty(key)) {
                target[key] = this.clone(source[key]);
            }
        }
        return target;
    }
}

const testObj = {
    name: 'deepClone',
    a: [1,3,4,5, {name: 'xiao花'}],
    b(){
        console.log(this.name);
    },
    c: /^[0-9]{1-3}$/,
    d: new Date(),
    e: 1233
}

const deepClone = new DeepClone();

const copy = deepClone.clone(testObj);

copy.name = '小明';
copy.b(); // 'deepClone'
testObj.b(); // '小明'
一般情况下的使用应该还是够的, 存在递归爆栈的风险