JavaScript中如何使用递归完成对对象的深拷贝

先上代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        obj = {
            a : 1,
            b : 2,
            c : 3,
            d : {
                e : 4
            },
            f : [1,2,3]
        }

        function deepcopy(obj) {
        	// 如果obj是数组,返回数组的深拷贝
            if (Array.isArray(obj)){
            	// 巧妙利用slice()方法完成深拷贝
                return obj.slice()
             // 利用toString()方法判断obj是否为对象
            }else if (obj.toString() === '[object Object]'){
                // 将对象转化为二维数组
                var arr = Object.entries(obj)
                var newobj = {}
                for (var i = 0; i < arr.length; i++){
                    if(typeof arr[i][1] != 'object'){
                        // 如果属性类型不是object,将属性添加到新对象中
                        // 这里为什么不用toString()方法,很重要,下面会讲
                        newobj[arr[i][0]] = arr[i][1]   
                    } else {
                        // 否则再次调用deepcopy函数(递归)
                        newobj[arr[i][0]] = deepcopy(arr[i][1])
                    }
                }
                // 返回新对象
                return newobj
            } else {
                // obj不是对象时返回函数或其它原始数据类型
                return obj
            }                  
        }
        newobj = deepcopy(obj)
        // console.log(newobj);
        newobj['c'] = 2
        newobj['d']['e'] = 5
        newobj['f'][0] = 9
        console.log(newobj); 
        // newobj = {
        //     a : 1,
        //     b : 2,
        //     c : 2,
        //     d : {
        //         e : 5
        //     },
        //     f : [9,2,3]
        // }
        console.log(obj);
        // obj = { 
        //     a : 1,
        //     b : 2,
        //     c : 3,
        //     d : {
        //         e : 4
        //     },
        //     f : [1,2,3]
        // }
    </script>
</body>
</html>

        为什么31行不再使用toString()方法判断属性是否为'[object, Object]',而使用typeof判断,是因为如果原对象中有属性值为数组的,如f : [1, 2, 3],需要使它进行递归使其进行深拷贝,因为数组是引用数据类型,如果不深拷贝,改变原对象里数组的值,新对象也会改变,这样就不算对象的深拷贝了。而且typeof 数组 和 typeof 对象 的值都是'object',这样判断能使数组和对象都进入else分支进行递归。

        如最后注释中的结果一样,改变新对象的属性值对旧对象不造成影响,反之亦然,两个对象互相独立。如此便完成了对对象的深拷贝。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值