深拷贝与浅拷贝

深拷贝

  • 深拷贝在进行深拷贝时,会拷贝所有的属性,并且如果这些属性是对象,也会对这些对象进行深拷贝,直到最底层的基本数据类型为止
深拷贝的方法:
  • for in 遍历+递归的方式
<script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name:"张三",
            age:18,
            info:{
                address1:"深圳",
                address2:"江西"
            },
            hobby:["唱","条","rap","篮球","music"]
        }

        const newObj = {}

        // 深拷贝
        function fn(newObj,oldObj){
            for(let key in oldObj){
                if(Object.prototype.toString.call(oldObj[key]) === '[object Object]'){
                    newObj[key] = {} //相对于创建一个新的空间
                    // 递归
                    fn(newObj[key],oldObj[key])
                }
                else if(Object.prototype.toString.call(oldObj[key]) === '[object Array]'){
                    newObj[key] = [] //相对于创建一个新的空间
                    fn(newObj[key],oldObj[key]) //使用递归
                }else{
                    // newObj[name] = oldObj[name] => 此时
                    newObj[key] = oldObj[key]
                }
            }
        }
        fn(newObj,obj)

        console.log(newObj,obj);
        console.log(newObj === obj);
        console.log(newObj.info === obj.info);
    </script>
  • JSON数据转换的方式
    但是深拷贝用此方法可能会造成对象内方法的丢失
<script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name:"张三",
            age:18,
            info:{
                address1:"深圳",
                address2:"江西"
            },
            hobby:['唱','跳','rap','篮球','music']
        }

        // 用JSON数据也可以实现深拷贝
        const jsonstr = JSON.stringify(obj)
        const newObj = JSON.parse(jsonstr)  //深拷贝

        console.log(newObj,obj);
        console.log(newObj === obj);
        console.log(newObj.info === obj.info);
    </script>
  • 引用lodash.js 创建深拷贝 const newObj = _.cloneDeep(obj)
<script src="./lodash.js"></script>
    <script>
        const obj = {
            name:"张三",
            age:18,
            info:{
                address1:"深圳",
                address2:"江西"
            },
            hobby:["唱","跳","rap","篮球","music"]
        }

        const newObj = _.cloneDeep(obj)
        console.log(newObj,obj);
        console.log(newObj === obj);
        console.log(newObj.info === obj.info);
    </script>
  • 扩展运算符
    当元素是一层数组或是对象时,也即元素只是简单类型的元素,那么三个点此时是深拷贝

    此处obj1和obj没有关系

浅拷贝

  • 浅拷贝只会拷贝对象的第一层属性,如果这些属性是对象,则不会对这些对象进行拷贝,而是直接复制对象的引用。这意味着,对于浅拷贝后的对象,如果原对象的属性值发生了变化,浅拷贝后的对象的属性值也会跟着发生变化
浅拷贝的方法:
  • for in 遍历+递归的方式
<script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name:"张三",
            age:18,
            info:{
                address1:"深圳",
                address2:"江西"
            },
            hobby:["唱","跳","rap","篮球","music"]
        }

        /* const newObj = obj //这种方式 => 不叫做拷贝 它只是把obj存储的地址复制一份  交给newObj */
        const newObj = {}
        // 需要遍历 将obj里面的内容都遍历一遍 赋值给newObj
        for(let key in obj){
            newObj[key] = obj[key]
        }
        console.log(obj === newObj);  //false
        console.log(obj.info == newObj.info);  //true 因为只拷贝第一层 后面层级的引用指向同一个堆内存中地址
    </script>
  • 三点运算符
<script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name: "张三",
            age: 18,
            info: {
                address1: "深圳",
                address2: "江西"
            },
            hobby: ["唱", "跳", "rap", "篮球", "music"]
        }

        /*
            三点运算符实现浅拷贝 
         */
        const newObj = { ...obj } //浅拷贝
        console.log(obj === newObj);  //false
        console.log(obj.info == newObj.info);  //true

    </script>
  • Object.assign() 可以把任意多个的源对象自身的可枚举属性拷贝给目标对象
<script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name: "张三",
            age: 18,
            info: {
                address1: "深圳",
                address2: "江西"
            },
            hobby: ["唱", "跳", "rap", "篮球", "music"]
        }

        /*
            Object.assign(浅拷贝的目标对象,浅拷贝的源对象) 
         */
        const newObj = {}
        Object.assign(newObj,obj)  //浅拷贝
        console.log(obj,newObj);
        console.log(obj === newObj);  //false
        console.log(obj.info == newObj.info); //true
    </script>
  • 引用lodash.js 创建浅拷贝 const newObj = _.clone(obj)
<script src="./lodash.js"></script>
    <script>
        // 将一个对象里面的内容只拷贝一层
        const obj = {
            name:"张三",
            age:18,
            info:{
                address1:"深圳",
                address2:"江西"
            },
            hobby:["唱","跳","rap","篮球","music"]
        }
        const newObj = _.clone(obj)  //浅拷贝
        console.log(obj,newObj);
        console.log(obj === newObj);  //true
        console.log(obj.info === newObj.info); //false
    </script>

lodash.js文件可以通过Boot CDN官网进行下载或者直接请求网络链接
使用方法进入Lodash官网搜索深拷贝和浅拷贝的使用

两者的区别

  • 深拷贝生成的新的对象和原对象没有关系
  • 对于浅拷贝生成的新对象,如果原对象发生改变,只要修改的不是第一层变量,那么拷贝的新对象会随之改变,因为拷贝的是对象引用,与原对象属性在堆内存中指向同一个地址,但是如果改变的是第一层的变量,那么新对象就不会修改,因为在栈内存中它们是不同的属性,互不影响
posted @   饼MIN  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示