JavaScript的深浅拷贝详解

目录

1.拷贝

1.1 拷贝产生的原因

1.2 拷贝的含义

2.浅拷贝

2.1 功能

2.2 使用方法

3.深拷贝

3.1 功能

3.2 使用方式

1.递归法:

2.lodash/cloneDeep(lodash库)

3.通过JSON.stringify()实现

1.拷贝

1.1 拷贝产生的原因

原始值按值复制,对象值(引用类型)只复制指针,真正的数据拷贝只有在你显式写出或使用深拷贝方法时才会发生。下述代码例子:

const obj = {
    name:'pink',
    age:18
}
//目的是对o进行操作
const o = obj
o.age = 20
//此时打印后,o和obj的age都变成20,是因为o在栈中开辟的是地址空间,该地址指向obj在堆区开辟的空间,这就会对原数据进行了修改
console.log(o)
console.log(obj)

1.2 拷贝的含义

拷贝就是把一份数据完整复制出另一份,使新旧两份互不影响

2.浅拷贝

2.1 功能

浅拷贝对象,只拷贝外面的那层,如果对象里面还有对象则如(o.family.baby修改时o和obj的baby都会修改)。浅拷贝只复制对象本身和第一层属性,嵌套对象仍共享引用。

2.2 使用方法

const obj = {
    name:'pink',
    age:18,
    family:{
        baby:'red'
    }
}
//此时的o中已经有一个新对象了
//方法一:使用扩展运算符(...)
const o = {...obj}

//方法二:通过assign将obj复制给o
const o = {}
Object.assign(o,obj)
o.age = 20
//此时o.age和obj.age就变得不同

3.深拷贝

3.1 功能

深拷贝递归复制所有层级,新旧对象完全独立。

3.2 使用方式

1.递归法:

//实现深拷贝
const obj = {
    name:'pink',
    age:18,
    hobby:['ball','swing'],
    family:{
        baby:'red'
    }
}
const o = {}
function deepCopy(newObj,oldObj){
    for(let k in oldObj){
        //k为属性名  oldObj为属性值
        //一定先写Array再写Object,因为数组也是对象,先筛选数组后对象
        if(oldObj[k] instanceof Array){
            //若为数组则转化为数组去接收
            newObj[k] = []
            deepCopy(newObj[k], oldObj[k])
        }
        else if(oldObj[k] instanceof Object){
            //若为对象,则转为对象去接收
            newObj[k] = {}
            deepCopy(newObj[k], oldObj[k])
        }else{
            newObj[k] = oldObj[k]
        }
    }
    return newObj
}
deepCopy(o,obj)

2.lodash/cloneDeep(lodash库)

//npm i lodash.clonedeep下载lodash库,然后进行导入
import cloneDeep from 'lodash.clonedeep';

const obj = {
    name:'pink',
    age:18,
    hobby:['ball','swing'],
    family:{
        baby:'red'
    }
}
//此时直接完成深拷贝,并且也将数组和对象进行了拷贝
const o = _cloneDeep(obj)
o.family.baby = 'black'//只改变了o里的baby

3.通过JSON.stringify()实现

const obj = {
    name:'pink',
    age:18,
    hobby:['ball','swing'],
    family:{
        baby:'red'
    }
}
//先将obj转化为JSON字符串,然后JSON.parse再在堆区创建一个新的空间把JSON字符串转化为JS对象存进去
const o = JSON.parse(JSON.stringify(obj))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值