JS进阶-深浅拷贝

理解深浅拷贝先理解什么是引用类型:

引用类型与值类型的区别:

值类型:var a = ‘hello’;var b = a;//值类型直接复制  

引用类型:var a = {x:1,y:2}

引用类型的变量(a)是一个对象({x:1,y:2})内存地址的指针,引用类型是指存储在内存中的对象,通过引用(即访问内存地址)来访问这些对象

浅拷贝

只复制对象的第一层属性,嵌套对象仍然共享引用。

第一属性的解释:嵌套对象外的属性称为第一属性。

语法:Object.assign({}, obj1);解析:浅拷贝方法,参数1定义数据类型,图中为一个对象花括号,参数2,定义所拷贝的对象。参考如下代码:

let obj1 = { name: "Kimi", address: { city: "Beijing" } };
let obj2 = Object.assign({}, obj1);
obj2.address.city = "Shanghai";
console.log(obj1); // 输出 { name: "Kimi", address: { city: "Shanghai" } }

代码逻辑:定义了两个引用类型obj1和obj2,obj2浅拷贝了obj1,代码中修改了obj2.address.city的值,后面输出obj1对象,结果表示了在浅拷贝中嵌套对象的修改会共享引用,而且第一属性的修改不会共享,即各自值类型的修改不会互相影响。

深拷贝

完全复制对象及其嵌套对象。与浅拷贝相比,第一属性和嵌套对象的修改不会共享引用。

语法:JSON.parse(JSON.stringify(obj1));

            分解说明:JSON.stringify(obj1),把对象那个obj1转换为json字符串,然后

JSON.parse,将json字符串转换为json对象。组合起来实现深拷贝。

参考代码:

let obj1 = { name: "Kimi", address: { city: "Beijing" } };
let obj2 = JSON.parse(JSON.stringify(obj1));
obj2.address.city = "Shanghai";
console.log(obj1); // 输出 { name: "Kimi", address: { city: "Beijing" } }

代码逻辑:定义了两个引用类型obj1和obj2,obj2深拷贝了obj1,代码中修改了obj2.address.city的值,后面输出obj1对象,结果表示了在深拷贝中第一属性和嵌套对象的修改不会共享引用。

深拷贝的多种使用

第一种使用json字符串转换实现深拷贝,

第二种通过递归手搓实现深拷贝

第三种利用lodash.js库里面的”_.cloneDeep”,此处未做演示。

下面使用递归实现深拷贝。

<script>
    // 声明一个对象,实现深拷贝
    // 深拷贝:对象的属性值是基本数据类型,直接赋值即可
    let obj = {
        uname: "zhangsan",
        age: 20,
        hobby: ['sing', 'dancing']
    }
    let o = {}
        // 定义一个深拷贝方法,参数:新对象,旧对象
    function deepCopy(newobj, oldobj) {
        for (let k in oldobj) {
            // 处理嵌套对象的问题,如果属性值是对象或者数组,则继续递归,即执行本函数
            if (oldobj[k] instanceof Object) {
                newobj[k] = []
                deepCopy(newobj[k], oldobj[k])
            } else {
                //如果属性值是基本数据类型,直接赋值
                newobj[k] = oldobj[k]
            }
        }
    }
    deepCopy(o, obj);
    o.age = 22
    o.hobby[0] = 'rap'
    console.log(o); // {uname: 'zhangsan', age: 22, hobby:['rap', 'dancing']}
    console.log(obj); // {uname: 'zhangsan', age: 20, hobby:['sing', 'dancing']}
</script>

代码逻辑:声明一个对象obj,内置有一个嵌套对数组对象hobby,,以及另一个空值对象o,定义一个深拷贝的方法,包含有两个参数,for循环遍历旧对象,循环判断旧对象属性值是一个对象,还是基本数据类型;如果是一个对象,那么将设置参数新对象为一个空值对象,递归该深拷贝方法循环判断并赋值,否则直接赋值。尝试修改对象o的属性值,可以发现,对象obj的属性值不会受影响,由此深拷贝得以实现。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值