Skip to content
本页目录

deep clone 深拷贝

对象或者数组对象的深拷贝,是个绕不开的话题,日常项目中,如果是简单的单层对象拷贝,或者简单的数组拷贝,使用 JS 的内置方法即可实现,如:

  • 数组
    • concat()
    • [...arr]
  • 对象
    • Object.assign({}, obj)
    • {...obj}

但以上方式只是实现了首层的深拷贝,对于项目中实际情况,我们还是需要做到每一层级的拷贝。

1. JSON 序列化实现

这个就不多说了,可以查看 JSON 章节,有缺陷,但一般基本够用

2. 递归实现

JS
// 丐版
function deepClone(target) {
    let cloneTarget = {};

    for(let key in target) {
        if(typeof target[key] === 'object') {
            cloneTarget[key] = deepClone(target[key])
        } else {
            cloneTarget[key] = target[key]
        }
    }

    return cloneTarget
}
// 丐版
function deepClone(target) {
    let cloneTarget = {};

    for(let key in target) {
        if(typeof target[key] === 'object') {
            cloneTarget[key] = deepClone(target[key])
        } else {
            cloneTarget[key] = target[key]
        }
    }

    return cloneTarget
}
JS
function deepCopy(target){ 
    //此数组解决了循环引用和相同引用的问题,它存放已经递归到的目标对象 
    let copyed_objs = [];

    function _deepCopy(target){ 

        if(!target || (typeof target !== 'object')){
            return target;
        }
        
        const len = copyed_objs.length;

        for(let i= 0; i < len; i++){
            if(copyed_objs[i].target === target){
                return copyed_objs[i].copyTarget;
            }
        }

        let obj = {};

        if(Array.isArray(target)){
            obj = [];//处理target是数组的情况 
        }

        copyed_objs.push({target:target,copyTarget:obj}) 

        Object.keys(target).forEach(key=>{ 

            if(obj[key]) { 
                return;
            }

            obj[key] = _deepCopy(target[key]);
        }); 

        return obj;
    }

    return _deepCopy(target);
}
function deepCopy(target){ 
    //此数组解决了循环引用和相同引用的问题,它存放已经递归到的目标对象 
    let copyed_objs = [];

    function _deepCopy(target){ 

        if(!target || (typeof target !== 'object')){
            return target;
        }
        
        const len = copyed_objs.length;

        for(let i= 0; i < len; i++){
            if(copyed_objs[i].target === target){
                return copyed_objs[i].copyTarget;
            }
        }

        let obj = {};

        if(Array.isArray(target)){
            obj = [];//处理target是数组的情况 
        }

        copyed_objs.push({target:target,copyTarget:obj}) 

        Object.keys(target).forEach(key=>{ 

            if(obj[key]) { 
                return;
            }

            obj[key] = _deepCopy(target[key]);
        }); 

        return obj;
    }

    return _deepCopy(target);
}