【深拷贝与浅拷贝】

浅拷贝

概述:

简单说浅拷贝就是只拷贝第一层的值,其他后面的拷贝是拷贝地址。相当于拷贝了一个快捷方式,当你在原来的基础上进行更改时,后面拷贝的内容(快捷方式)都会被更改。

或者你可以理解为,浅拷贝并没有拷贝这个对象,而只是拷贝了这个对象的引用

下面举例6种实现浅拷贝的方法:

1、Object.assign实现浅拷贝

let obj = {name:'jack',list:[1,2,3],params:{data:'ok'}}
let copyObj = Object.assign({},obj)
console.log(obj == copyObj) //false
console.log(obj.list == copyObj.list) //true

在这里说明一下,为什么obj == copyobj为 false,为什么obj.list == copyObj.list又为 true。
因为浅拷贝只是拷贝了第一层的值,不复制对象本身,新旧对象还是共享同一块内存

2、Array.prototype.concat

//数组的浅拷贝
let arr = [{
    username:'jack',
    password:'123'
},
           {
               username:'tom',
               password:'456'
           }]
//使用concat连接
let copyArr = [].concat(arr)
console.log(copyArr == arr) //false
console.log(copyArr[0] == arr[0]) //true

3、使用数组的截取来实现浅拷贝

//使用数组的截取来实现浅拷贝
let copyArr1 = arr.slice()
console.log(copyArr1 == arr) //false
console.log(copyArr1[0] == arr[0]) //true

4、扩展运算符 …

//使用扩展运算符
let copyArr2 = [...arr]
console.log(copyArr2 == arr); //false
console.log(copyArr2[0] == arr[0]) //true

5、自定义实现函数的浅拷贝

//函数实现浅拷贝
function copy(obj){
    //创建一个新的对象
    let constructor = obj.constructor
    let copyObj = new constructor()
    for(let key in obj){
        copyObj[key] = obj[key]
    }
    return copyObj
}
let copyArr3 = copy(arr)
console.log(copyArr3 == arr); //false
console.log(copyArr3[0] == arr[0]) //true
let copyObj1 = copy(obj)
console.log(obj == copyObj1) //false
console.log(obj.list == copyObj1.list) //true

6、使用第三方工具(lodash.js) _.clone

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
    //浅拷贝 拷贝的对象 返回一个新的对象
    let obj2 = {name:'jack',list:[1,2,3],params:{data:'ok'}}
    let copyObj3 = _.clone(obj2)
    console.log(obj2 == copyObj3)//false
    console.log(obj2.list == copyObj3.list)//true
</script>

lodash的中文文档:

https://www.lodashjs.com/

深拷贝

概述:

深拷贝是拷贝所有的内容,这俩个内容只有里面的值是相同的,其他引用地址都是不一样的。相当于你用u盘拷贝一份资料,那么这份资料跟拷贝的那份资料是没有任何关系的,但是里面显示的内容是一样的。

下面举例3种实现深拷贝的方法:

1、序列化和反序列化 (JSON.stringify JSON.parse)

//使用序列化和反序列化
let obj = {
    list:[{
        name:"苹果"
    },
          {
              name:"香蕉"
          }]
}
//进行深拷贝
let copyObj = JSON.parse(JSON.stringify(obj))
console.log(copyObj == obj);//false
console.log(copyObj.list == obj.list);//false
console.log(copyObj.list[0] == obj.list[0]);//false

2、使用第三方工具 lodash.js (_.cloneDeep)

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
<script>
    let copyObj1 = _.cloneDeep(obj)
    console.log(copyObj1 == obj);//false
    console.log(copyObj1.list == obj.list);//false
    console.log(copyObj1.list[0] == obj.list[0]);//false
</script>

3、自定义函数实现深拷贝(用递归实现)

//自定义函数实现深拷贝(递归)
function deepClone(obj) {
    //判断当前你传入的参数是否是一个对象
    if (!(typeof obj == 'object' && obj)) {
        return obj
    }
    //如果他是数组 我就赋值为数组 如果是对象就赋值为
    let copyObj = obj instanceof Array ? [] : {}
    //遍历传入的对象
    for (let key in obj) {
        //将对应的内容进行赋值
        copyObj[key] = deepClone(obj[key])
    }
    return copyObj
}
let copyObj2 = deepClone(obj)
console.log(copyObj2);
console.log(copyObj2 == obj);//false
console.log(copyObj2.list == obj.list);//false
console.log(copyObj2.list[0] == obj.list[0]);//false

总结:浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值