8.ES6新增(七)①基本和引用类型在赋值和拷贝的区别②直接赋值③浅拷贝concat、slice、扩展运算符...、assign④深拷贝用JSON,js和JSON相互转换⑤递归实现深拷贝

首先我们需要掌握一些基本的知识点:
1、在JS中,数据类型分为:
基本数据类型:Number,String,Undefined,Null,Boolean,Symbol,BigInt
引用数据类型:(object) 分为 👉👉Array, function, date, RegExp


2、JS中,栈(stack)和 堆(heap):
栈(stack)为自动分配的内存空间,它由系统自动释放。
堆(heap)为动态分配内存空间,大小不定,不会自动释放。

栈里存放:基本类型全部和引用类型的名字
堆里存放:引用类型的值

目录

 一: 直接赋值

1.  基本数据类型:赋值,赋值之后两个变量互不影响。非同一地址值

2.  引用数据类型:赋值,两个变量具有相同的地址值,相互之间有影响。同一地址值

浅拷贝:新数据与旧数据共享一块内存 

深拷贝:自己开辟一个新内存,

二:浅拷贝:只拷贝第一层(只有第一层不是同一地址值)

1:数组浅拷贝的方法

2.  对象浅拷贝的方法

使用 assign 方法创建对象 (assign之前学过用来做对象的合并)

三:深拷贝 就是 开辟属于自己的新地址,逐个将原数据的属性添加到新地址内。修改新数据不影响旧数据(都不是同一地址值)

实现方法 :JSON实现深拷贝,缺陷: 不能复制方法

1.首先JSON.stringify(JS对象) 将 JS 旧对象转化为 JSON 格式的字符串  

2.然后JSON.parse(字符串名) 将 JSON 格式的字符串转化为 JS 新对象,用新变量接收

四: 用递归实现深拷贝


 一: 直接赋值

1.  基本数据类型:赋值,赋值之后两个变量互不影响。非同一地址值

        let a = 10;
        let b = a;
        b = 100;
        console.log(a)   //10
        console.log(b)   //100

2.  引用数据类型:赋值,两个变量具有相同的地址值,相互之间有影响。同一地址值

        let x = [1, 2, 3, 4, 5]
        let y = x
        y[0] = 666
        console.log(x)    //[666,2,3,4,5]
        console.log(y)    //[666,2,3,4,5]
        let a = [1, { name: '与世无争' }, 3, 4];
        let newA = a;
        a[0] = 666                //一级属性
        a[1].name = '大富大贵';     //二级属性
        console.log(a);    //[666,{name:'大富大贵'}, 3, 4]
        console.log(newA); //[666,{name:'大富大贵'}, 3, 4]

浅拷贝:新数据与旧数据共享一块内存 

深拷贝:自己开辟一个新内存,

二:浅拷贝:只拷贝第一层(只有第一层不是同一地址值)

1:数组浅拷贝的方法

  • ① 用数组的concat方法 : 基本拷值,引用拷地址值

  • ②  用数组的slice方法 : 基本拷值,引用拷地址值

  • ③  扩展运算符...

        let a = [1,{name:'羊'},[0,0,0,]]
        let b = a.slice(0)
        // let b = [].concat(a)
        // let b = [...a]
        a[0] = 10
        a[1].name = '杨'
        a[2][0] = 3   
        console.log(a)   // [ 10, {name:'杨'}, [3, 0, 0] ]
        console.log(b)   // [ 1, {name:'杨'}, [3, 0, 0] ] 

2.  对象浅拷贝的方法

使用 assign 方法创建对象 (assign之前学过用来做对象的合并)

        //使用 assign 方法创建对象 (assign之前学过用来做对象的合并)
        const school = {
            name: "尚硅谷",
            pos: ['北京', '上海', '深圳']
        }

        const newSchool = Object.assign({}, school);

        newSchool.name = 'atguigu';    //基本类型原数组不变
        newSchool.pos[0] = 'beijing';  //引用类型原素组改变

        console.log(school);   //{name:'尚硅谷',post:['beijing','上海','深圳']}
        console.log(newSchool);{name:'atguigu',post:['beijing','上海','深圳']}

三:深拷贝 就是 开辟属于自己的新地址,逐个将原数据的属性添加到新地址内。修改新数据不影响旧数据(都不是同一地址值)

实现方法 :JSON实现深拷贝,缺陷: 不能复制方法

1.首先JSON.stringify(JS对象) 将 JS 旧对象转化为 JSON 格式的字符串  

2.然后JSON.parse(字符串名) 将 JSON 格式的字符串转化为 JS 新对象,用新变量接收

此时新变量就是深拷贝,地址值不一样了

        let school = {
            name: '尚硅谷',
            pos: ['北京', '上海', '深圳'],
            founder: {
                name: '刚哥'
            },
            change: function () {
                console.log('改变');
            }
        }

        //将 JS对象 转为 JSON 格式的 字符串 
        let str = JSON.stringify(school);
        console.log(str);         //{"name":"尚硅谷","pos":["北京","上海","深圳"],"founder":{"name":"刚哥"}}
        console.log(typeof str);  //string
        //将 JSON对象 转为 JS对象
        let newSchool = JSON.parse(str);
        console.log(newSchool);   //{name: "尚硅谷", pos: Array(3), founder: {…}}

        //测试深拷贝
        newSchool.name = '嘿嘿嘿'
        newSchool.pos[0] = 'beijing';
        console.log(school);     //{"name":"尚硅谷","pos":["北京","上海","深圳"],"founder":{"name":"刚哥"},change: ƒ}
        console.log(newSchool);  //{"name":"嘿嘿嘿","pos":["beijing","上海","深圳"],"founder":{"name":"刚哥"}}

四: 用递归实现深拷贝

    1.fn方法:判断 a 的类型,如果是基本数据类型 直接return值,如果是引用数据类型 进入 skb方法

    2.skb方法:开辟新值: a是数组给[];是对象给{}

    3.遍历a内部值,如果是基本数据类型,新值直接添加此值

                            如果是引用类型,重复2的操作

    <script>
        let a = {
            name:'yy',
            arr:[10,{name:'数组',age:'18'}],
        }
        let b = fn(a)

        function fn(a){
            if(typeof a ==="object" && a !== null){
                return skb(a)
            }else{
                return a
            }
        }
        function skb(old){                                 
                var container = Array.isArray(old)?[]:{}   
                for(let i in old){                                 
                    if(typeof old[i] === "object" && old[i] !== null){
                        container[i] = skb(old[i]) // skb(arr:[10,{name:'数组',age:'18'}])
                    }else{
                        container[i] = old[i]
                    }
                    
                }
                return container
            }

        b.name = '嘿嘿'
        b.arr[1].name = '嘿嘿'
        console.log(a)
        console.log(b)
    </script>

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值