JS:浅拷贝和深拷贝

本文详细介绍了JavaScript中的浅拷贝和深拷贝概念,通过实例展示了浅拷贝的三种实现方式,包括手动复制、扩展运算符和`Object.assign()`。同时,深入探讨了深拷贝的两种实现方法:JSON序列化及其局限性,以及递归实现深拷贝。文章强调了浅拷贝只复制最外层属性,而深拷贝会复制所有层级的属性,确保新对象与原对象相互独立。

什么是浅拷贝?

误区:浅拷贝不等于赋值!!

浅拷贝的概念:循环对象,把对象中最外层的属性拷贝出来,给到一个新对象。如果最外层的属性中有复杂数据类型,那么拷贝的就是内存地址

实现浅拷贝有三种方式:

第一种代码示例:

<script>
        let obj = {
            id:1,
            name:"孙悟空",
            age:14,
            info:{
                address:"花果山"
            }
        }
        let o1 = {};

        // obj 就是要浅拷贝的对象
        for(let k in obj){
            // k是属性名 obj[k]是属性值
            o1[k] = obj[k];
        }
        // 此时是浅拷贝,o1里的info和obj里的info指向的是同一个内存地址
        o1.info.address = "天宫"; // 修改了o1里的address,obj里的address也会被修改
        console.log(obj.info.address); // 天宫
</script>

第二种代码示例(最简单也最常用):

<script>
        let obj = {
            id:1,
            name:"孙悟空",
            age:14,
            info:{
                address:"花果山"
            }
        }
        // 使用点语法也可以实现浅拷贝
        let o1 = {...obj};
        console.log(o1)
</script>

ES6中新增了一个浅拷贝的方法:Object.assign(target,sources);

assign单词的意思是分配

参数:target 要拷贝给哪个对象,也就是o1,sources 被拷贝的对象,也就是obj

第三种代码示例:

<script>
        let obj = {
            id:1,
            name:"孙悟空",
            age:14,
            info:{
                address:"花果山"
            }
        }

        let o1 = {};
        for(let k in obj){
            // k是属性名 obj[k]是属性值
            o1[k] = obj[k];
        }

        // 同样也是浅拷贝
        // 把obj对象的数据浅拷贝给新对象o1
        Object.assign(o1,obj);
        console.log(o1);
</script>

什么是深拷贝?

深拷贝的概念:把对象身上的每一层属性都进行拷贝,赋值给一个新对象

深拷贝有两种方式:

1.JSON序列化

<script>
     let obj = {
         id:1,
         name:"孙悟空",
         age:14,
         info:{
             address:"花果山"
         }
     }

    let jsonStr = JSON.stringify(obj)
    let o1 = JSON.parse(jsonStr)
    console.log(o1)
</script>

但JSON序列化有缺点

1)如果要拷贝的对象中数据很复杂,而且很多,那么转换的性能很低

2)不能被JSON识别的数据,不会被拷贝到新的对象中

2.自己写递归

<script>
    let obj = {
        id:1,
        name:"孙悟空",
        age:14,
        info:{
            address:"花果山"
        }
    }

    // 深拷贝obj对象中的数据到o1中
    // 参数obj表示的是要深拷贝的对象
    function deepClone(obj){
        // 判断是否需要进行深拷贝,如果是简单类型不需要,复杂类型则需要
        if(typeof obj !== 'object') return obj

        // 判断传递的obj是否是数组,如果是返回数组类型,否则返回对象类型
        let o1 = Array.isArray(obj) ? [] : {}
        for(let k in obj){
            // 只拷贝对象本身的属性,不拷贝原型身上的属性
            if(obj.hasOwnProperty(k)){
                o1[k] = deepClone(obj[k])
            }            
        }
        return o1
    }
    
    let o1 = deepClone(obj)
    o1.info.address = '天宫'
    console.log(obj.info.address) // 还是花果山,没有被修改
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值