一篇文章带你理解 js 深浅拷贝

本文详细解析了JavaScript中的深拷贝和浅拷贝概念,通过实例展示了它们的区别。文章还介绍了栈内存和堆内存的工作原理,并提供了一个实现深拷贝的递归方法。此外,讨论了JSON.stringify()和JSON.parse()在深拷贝中的限制。
摘要由CSDN通过智能技术生成

要了解 深浅拷贝我们需要先了解一下js的内存机制

 我们先写个例子更直观的去看一下

    let a = 10
    let b = a
    a = 20
    console.log(a, b);
    // 打印结果 20,10
    let obj1 = { name: "小明" }
    let obj2 = obj1
    obj1.name = "小红"
    console.log(obj1.name, obj2.name);
    // 打印结果 小红,小红

上图我们可以看出b=a ,a的值发生改变,但是b的值没有发生改变,而对象的赋值则会改变, 下面我们先看一下 js 的栈内存堆内存

 

栈内存 主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、  Null,**以及对象变量的指针

堆内存 主要负责像对象Object这种变量类型的存储

深拷贝:赋值时值完全复制,完全的copy,对其中一个作出改变,不会影响另一个

浅拷贝:赋值时,引用赋值,相当于取了一个别名。对其中一个修改,会影响另一个
基本类型是储存在栈内存空间的引用类型的堆内存空间

 从上图可以看出  基本数据类型赋值为深拷贝  引用数据类型赋值为浅拷贝,这里也就解释了为啥

JSON.stringify(),JSON.parse()可以进行深拷贝,但是这个有bug,大家可以下去百度一下

接下来我们一步一步的写一个深拷贝的方法

 我们先定义一个方法 通过for in来便利对象 ,并通过hasOwnProperty来检测一下对象是否包含特  定的自身属性

    let obj1 = { name: "小明" }
    function deepClone(source) {
        let targetObj = Array.isArray( source ) ? [] : {} //这里我们需要兼容一下数组
        for (const key in source) {
            if (source.hasOwnProperty(key)) {
                //判断对象是否包含特定的自身(非继承)属性,防止有些对象属性被delete删除掉
                targetObj[key] = source[key]
                //给新对象通过key值赋值拷贝
                console.log(key);
            }
        }
        return targetObj
    }
    let obj2 = deepClone(obj1)
    obj1.name = "小红"
    console.log(obj1.name, obj2.name);
    //打印结果 小红 , 小明

上面这个方法只能拷贝外层,所以我们需要用到递归去深层次的拷贝 ,

    let obj1 = { name: "小明", people: { age: 13 } }
    function deepClone(source) {
        if (typeof source !== 'object') return source//这里不是对象直接返回
        let targetObj = Array.isArray( source ) ? [] : {} //数组兼容
        for (const key in source) {
            if (source.hasOwnProperty(key)) {
                //判断对象是否包含特定的自身(非继承)属性,防止有些对象属性被delete删除掉
                if (source[key] && typeof source[key] === 'object') {
                    targetObj[key]=deepClone(source[key]) //通过递归进行深层次拷贝
                } else {
                    targetObj[key] = source[key]
                }
            }
        }
        return targetObj
    }
    let obj2 = deepClone(obj1)
    obj1.name = "小红"
    console.log(obj1, obj2);

上面这个应该看懂问题不大吧!我就不做过多解释了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值