Web前端之路

JS 深度克隆

2020-03-04  本文已影响0人  太妃榛果拿铁

想要克隆一个对象或数组,如果只是普通的赋值,那么只是复制了浅层,深层的引用值其实指向的是同一块内存。

JSON克隆法

第一次看到这种克隆方法,把我惊呆了,还能这样克隆?

function JSONDeepClone(origin) {
    return JSON.parse(JSON.stringify(origin));
}

但这个方法也有缺点,当对象中包含【Function函数、Date日期对象、RegExp正则对象】时,克隆出的对象无法复制这些属性。

递归克隆

再很久以前学基础js的时候,就自己试着写了一下递归深度克隆,能深度克隆数组和对象。

function deepClone(origin) {
    let target;
    // 判断传入的origin的类型
    if (getType(origin) == '[object Object]') {
        target = {};
    }else if (getType(origin) == '[object Array]') {
        target = [];
    }else{
        return origin;
    }
    // 遍历值,for-in可以遍历数组、对象
    for(const key in origin){
        // 如果值是数组或对象,递归继续克隆
        if (getType(origin[key]) == '[object Object]' || getType(origin[key]) == '[object Array]') {
            target[key] = deepClone(origin[key]);
        }
        //如果不是,直接赋值
        else{
            target[key] = origin[key];
        }
    }
    return target;
}

// 判断类型
function getType(sth) {
    return Object.prototype.toString.call(sth);
}

当然,这里还有缺陷。克隆出来的对象,函数、日期对象、正则对象等其实也是同一个引用。

对于解决日期对象,可以使用这种方法(同时在遍历值的时候,是否继续递归克隆的条件判断要多加上Date)

if (getType(origin) == '[object Date]') {
    return new Date(origin.getTime());
}

对于正则也是同样的思路,如果是[object RegExp],就new RegExp,用正则的一些属性获取被克隆的正则对象的信息

上一篇 下一篇

猜你喜欢

热点阅读