深拷贝和浅拷贝的区别

一、浅拷贝
只复制指向对象的指针,而不复制对象本身,新旧对象还是共享一块内存。

  1. object.assign(target,source)

用于将所有对可枚举属性的值从一个或多个源对象复制到目标对象,返回目标对象。
如果对象有重名属性,是后面的属性覆盖前面的。

        let target = {
            name: '小红',
            age: '23'
        }
        let source = {
                state: '睡觉',
                age: '99'
            }
        var result = Object.assign(target, source)
        result.name = '小蓝'
        console.log(target); //{name: "小蓝", age: "99", state: "睡觉"}
        console.log(result); //{name: "小蓝", age: "99", state: "睡觉"}
  1. 扩展运算符:针对一维数组和对象可以看成深拷贝,多维数组和对象就是浅拷贝

… 扩展运算符是自动遍历取值,可实现一层深拷贝。
解构是取出指定元素/属性,取代obj.name这种传统写法,多用于传参、嵌套解构的赋值等。
两者结合,即自动遍历一层再解构赋值,可实现灵活的深拷贝(单层)

        let target = {
            name: '小红',
            age: '23'
        }
        let newOBJ = {...target
        }
        newOBJ.age = '55'
        console.log(target);//{name: "小红", age: "23"}
        console.log(newOBJ);//{name: "小红", age: "55"}
  1. Array.contact()

该方法并不会改变现有数组,而是返回被连接的多个数组的一个副本。
要是修改数组中的某个对象属性会改变原数组。

        let array1 = [{
            name: 'lili'
        }]
        let array2 = array1.concat('six')
        console.log(array2); // [{name:'lili'}, "six"]
        console.log(array1); //[{name:'lili'}]
        //要是修改某个对象的值 例如:
        array2[0].name = 'hhhhh'
        //打印的值就会改变成
        console.log(array2); // [{name:'hhhhh'}, "six"]
        console.log(array1); //[{name:'hhhhh'}]
  1. Array.slice(start,end)

也是修改数组中的某个对昂属性会改变原数组

        let arr = ['1', '2', {
            name: 11
        }, '4', '5']
        let arr1 = arr.slice(0)
        arr1[1] = 'uuuu'
        console.log(arr1);//["1", "uuuu", {name:11}, "4", "5"]
        console.log(arr);//["1", "2", {name:11}, "4", "5"]
        //改变之后就会
        arr1[2].name = 'gaibianle'
        console.log(arr1); //["1", "uuuu", {name:gaibianle}, "4", "5"]
        console.log(arr); //["1", "2", {name:gaibianle}, "4", "5"]

二、深拷贝
开辟一个新的栈,两个对象的属性相同,但是对应两个不同的地址,新旧对象不共享一块内存,修改一个对象的属性,不会改变另一个对象的属性。

  1. JSON.parse(JSON.stringify())

本质就是先将js对象进行序列化,然后再反序列化还原js对象

缺点:
忽略undefined、symbol和函数
NAN和infinity对象,RegExp、Error对象都会返回空
不能解决循环引用的对象

  1. 循环递归使用
        function deepclone(obj) {
            const targetObj = obj.constructor === 'Array' ? [] : {}
            for (const key in obj) {
                if (obj.hasOwnProperty(key)) {
                    if (obj[key] && typeof obj[key] === 'Object') {
                        targetObj[key] = obj[key].constructor === 'Array' ? [] : {}
                        targetObj[key] = deepclone(obj[key])
                    } else {
                        targetObj[key] = obj[key]
                    }
                }
            }
            return targetObj;
        }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值