JavaScript对象深度克隆

来源:互联网 发布:淘宝客服辛苦吗 编辑:程序博客网 时间:2024/05/16 12:12

在某些应用场景中,我们可能需要深度克隆一个JavaScript对象,希望克隆的对象和原对象完全独立。

1、直接赋值其实是指向同一个对象。看下面的例子

    var obj1 = {age: 18};

    var obj2 = obj1;

    obj2.age = 20;

    console.log(obj1.age);    //输出20

    由此可见,直接赋值时:前后两个变量指向同一个对象,通过其中一个变量名改变对象值时,通过另外一个变量名输出的值也会变化。达不到克隆对象的目的。

2、使用for in循环出对象的属性,并依次增加到新对象中。看下面例子

    var obj1 = {age: 18, phone: {brand: 'huawei', price: 1599}};
    function cloneObj (obj) {
        var res = {};
        for(var i in obj){
            res[i] = obj1[i];
        }
        return res
    }
    var obj2 = cloneObj(obj1);
    obj2.age = 20;
    obj2.phone.price = 2000;
    console.log(obj1.age);    //输出18

    console.log(obj1.phone.price);    //输出2000

    我们发现age属性独立开了。但是改变obj2.phone.price时,obj1.phone.price也变化了。这是因为obj1的phone属性也是一个对象,赋值给obj2的phone属性时,其实他们指向的是同一个对象{brand: 'huawei', price: 1599},只是不同的引用而已。所以,以上cloneObj方法可以实现对象属性是基础数据类型时的克隆,但是当属性值是对象时就不能克隆了。此方法不能完全达到我们的目的,我把这种克隆称为浅层克隆。

3、使用for in循环出对象的属性,并依次增加到新对象中,当属性是对象时继续递归此操作。看下面例子

    var obj1 = {age: 18, phone: {brand: 'huawei', price: 1599}};
    function cloneObj (obj) {
        if (typeof obj !== 'object') {
            return obj    //基础数据类型直接返回
        }
        var res = Object.prototype.toString.call(obj) === '[object Array]' ? [] : {};    //判断是否是数组
        for(var i in obj){
            res[i] = typeof obj1[i] === 'object' ? cloneObj(obj1[i]) : obj1[i];    //基础数据类型直接赋值,对象时递归克隆操作
        }
        return res
    }
    var obj2 = cloneObj(obj1);
    obj2.age = 20;
    obj2.phone.price = 2000;
    console.log(obj1.age)    //18
    console.log(obj1.phone.price)    //1599

    我们发现age独立开了,phone属性也完全独立了,obj1和obj2不再有关联了。达到了我们深度克隆的目的

4、深度克隆关键点就在于属性值也是对象时要继续递归克隆每一个属性值,直到最里层。

    





    ------------------------ 分隔线呀分隔线 ------------------------------

    试着写写前端学习的历程,有错误之处欢迎拍砖(可以打脸)