js对象的深拷贝

原始值和引用值

在 ECMAScript 中,变量可以存在两种类型的值,即原始值和引用值。

原始值

存储在栈(stack)中的简单数据段,也就是说,它们的值直接存储在变量访问的位置。

引用值

存储在堆(heap)中的对象,也就是说,存储在变量处的值是一个指针(point),指向存储对象的内存处。

 

原始值 ------不会互相影响

 var a = 3;
 var b = a;
     b = 5;
     console.log(a); // 3
     console.log(b); // 5

引用值 -----会互相影响

var obj1 = {
        a: 1,
        b: 2,
        c: 3
    }
    var obj2 = { ...obj1 };
    obj2.a = 5;
    console.log(obj1.a);  // 5
    console.log(obj2.a);  // 5

    var arr1 = [1, 2, 3]
    var arr2 = [...arr1];
    arr2[0] = 3;
    console.log(arr1[0])  //3
    console.log(arr2[0])   //3

 

下面看一下如何深拷贝一个对象,即拷贝一个对象更改对象的值又不会互相影响

 

第一种 Object.assign() 

该方法只能拷贝一层的对象

例子

 var obj1 = {
        a: 1,
        b: 2,
        c: 3
    }
    var obj2 = Object.assign({}, obj1);
    obj2.a = 5;
    console.log(obj1.a);  // 1
    console.log(obj2.a);  // 5


    var arr1 = [1, 2, 3]
    var arr2 = Object.assign([], arr1);

    arr2[0] = 3;
    console.log(arr1[0])    //1
    console.log(arr2[0])   //3



    //以下的值不能个更改了----------------------------------
    var obj3 = {
        a: {
            a: 111
        },

    }
    var obj4 = Object.assign({}, obj3);;
    obj4.a.a = 'aaaaa';
    console.log(obj3.a.a);  // aaaaa
    console.log(obj4.a.a);  // aaaaa



    var arr3 = [{ a: 1, b: 2 }]
    var arr4 = Object.assign([], arr3);
    arr4[0].a = 'aaa';
    console.log(arr3[0].a)  //aaa
    console.log(arr4[0].a)   //aaa

 

第二种扩展符

该方法同第一种只能复制简单的一层的数据类型

例子

  var obj1 = {
        a: 1,
        b: 2,
        c: 3
    }
    var obj2 = Object.assign({}, obj1);
    obj2.a = 5;
    console.log(obj1.a);  // 1
    console.log(obj2.a);  // 5


    var arr1 = [1, 2, 3]
    var arr2 = Object.assign([], arr1);

    arr2[0] = 3;
    console.log(arr1[0])    //1
    console.log(arr2[0])   //3



    //以下的值不能个更改了----------------------------------

    var obj3 = {
        a: {
            a: 111
        },

    }
    var obj4 = { ...obj3 };
    obj4.a.a = 'aaaaa';
    console.log(obj3.a.a);  // aaaaa
    console.log(obj4.a.a);  // aaaaa




    var arr3 = [{ a: 1, b: 2 }]
    var arr4 = [...arr3];
    arr4[0].a = 'aaa';
    console.log(arr3[0].a)  //aaa
    console.log(arr4[0].a)   //aaa

第三种JSON转化

该方法不能更改值为undefined,fun(),正则等等值得对象

例子

{

        let obj1 = {
            a: 1,
            b: 2,
            c: 3
        }
        let objString = JSON.stringify(obj1);
        let obj2 = JSON.parse(objString);
        obj2.a = 5;
        console.log(obj1.a);  // 1
        console.log(obj2.a);  // 5
    }

    {
        let arr1 = [1, 2, 3]
        let objString = JSON.stringify(arr1);
        let arr2 = JSON.parse(objString);

        arr2[0] = 3;
        console.log(arr1[0])    //1
        console.log(arr2[0])   //3
    }


    {
        let obj3 = {
            a: {
                a: 111
            },

        }
        let objString = JSON.stringify(obj3);
        let obj4 = JSON.parse(objString);
        obj4.a.a = 'aaaaa';
        console.log(obj3.a.a);  // 111
        console.log(obj4.a.a);  // aaaaa
    }

    {
        let arr3 = [{ a: 1, b: 2 }]
        let objString = JSON.stringify(arr3);
        let arr4 = JSON.parse(objString);
        arr4[0].a = 'aaa';
        console.log(arr3[0].a)  //1
        console.log(arr4[0].a)   //aaa
    }


    //以下的不能更改-------------------------------------------
    {

        let obj1 = {
            a: '这样子的改不了哦',
            b: undefined,
            c: function () { },
            d: null,
            e: /a/
        }
        let objString = JSON.stringify(obj1);
        let obj2 = JSON.parse(objString);
        obj2.a = 5;
        console.log(obj1);
        /*
        a: "这样子的改不了哦"
        b: undefined
        c: ƒ ()
        d: null
        e: /a/
        */
        console.log(obj2);

        /*
        a: 5
        d: null
        e: {}
        */
    }


    {
        let arr1 = ['这样子的改不了哦', undefined, function () { }, null, /a/]
        let objString = JSON.stringify(arr1);
        let arr2 = JSON.parse(objString);

        arr2[0] = 3;
        console.log(arr1)   

        /*
        0: "这样子的改不了哦"
        1: undefined
        2: ƒ ()
        3: null
        4: /a/
        */
        console.log(arr2)  

        /*
        0: 3
        1: null
        2: null
        3: null
        4: {}*/
    }

 

封装方法

例子

封装的方法

// 定义一个深拷贝函数  接收目标target参数
    function deepClone(target) {
        // 定义一个变量
        let result;
        // 如果当前需要深拷贝的是一个对象的话
        if (typeof target === 'object') {
            // 如果是一个数组的话
            if (Array.isArray(target)) {
                result = []; // 将result赋值为一个数组,并且执行遍历
                for (let i in target) {
                    // 递归克隆数组中的每一项
                    result.push(deepClone(target[i]))
                }
                // 判断如果当前的值是null的话;直接赋值为null
            } else if (target === null) {
                result = null;
                // 判断如果当前的值是一个RegExp对象的话,直接赋值    
            } else if (target.constructor === RegExp) {
                result = target;
            } else {
                // 否则是普通对象,直接for in循环,递归赋值对象的所有值
                result = {};
                for (let i in target) {
                    result[i] = deepClone(target[i]);
                }
            }
            // 如果不是对象的话,就是基本数据类型,那么直接赋值
        } else {
            result = target;
        }
        // 返回最终结果
        return result;
    }

使用

    //拷贝一个对象
    let obj1 = {
        a: {
            c: /a/,
            d: undefined,
            b: null
        },
        b: function () {
            console.log(this.a)
        },
        c: [
            {
                a: 'c',
                b: /b/,
                c: undefined
            },
            'a',
            3
        ]
    }
    let obj2 = deepClone(obj1);
    obj2.a = {
        c: 2,
    }
    obj2.b = function () {
        console.log('你是不是傻啊')
    }

    console.log(obj1);
    console.log(obj2);


    //拷贝一个数组
    var arr1 = [{
        a: [1, 2, 3],
        b: function () { },
        c: undefined,
    }, {
        a: [1, 2, 3],
        b: function () { },
        c: undefined,
    }]

    let arr2 = deepClone(arr1);
    arr2[0].a = [1]
    arr2[0].b = {a:1}
    arr2[0].c = function(){}

    console.log(arr1);
    console.log(arr2);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值