浅拷贝与深拷贝

首先我们要知道,js有两大类数据类型:

1.值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、空(Null)、未定义(Undefined)、Symbol

2.引用数据类型(对象类型):对象(Object)、数组(Array)、函数(Function),还有两个特殊的对象:正则(RegExp)和日期(Date)。


由于值类型数据较简单,所以创建时候直接储存在栈内存中,在拷贝的时候,会新生成一份储存在栈中,两者互不影响。

而引用数据类型,由于数据结构较复杂,所以创建时候一般都是储存在堆内存中,然后会在栈中生成一份引用(里面保存的是该引用类型在堆内存中的地址,类似c语言的指针)。在拷贝的时候,不会重新在堆内存中生成一份数据,而是直接在栈内存中新生成一份引用指向原本的那个堆内存地址。所以浅拷贝的话,只是拷贝了一份地址,指向了同一个对象,并没有新生成一个对象。


如果我们想要得到原对象的一份真正的独立的复制体,我们就需要对其进行手动深拷贝,即遍历该对象的所有属性,并将其添加到那个复制体对象上面去。

这时候我们会遇到一个问题,如果对象上面的属性是另一个对象,这时候如果我们进行普通普通拷贝,就会遇到和上面同样的问题,所以我们需要对这个手动的深拷贝函数进行循环调用。


function deepClone(obj = {}) {
    if (typeof obj != 'object' || obj == null) {
        //如果传入的obj不是一个对象,那么就不需要进行深拷贝,值类型直接赋值就可以了
        return obj
    }

    //let newObj
    //判断obj是数组还是对象,以确认newObj的类型
    //obj instanceof Object ? newObj = {} : newObj = []

    //优化版
    let newObj = new obj.constructor

    //用for in 遍历obj的属性
    for(let index in obj){
        //只拷贝对象本身拥有的属性,不拷贝原型链上面的属性
        if(obj.hasOwnProperty(index)){
            //循环调用赋值,因为有可能碰到obj的某个属性同样也是一个对象的情况
            newObj[index]=deepClone(obj[index])
        } 
    }
    return newObj
}

 


上面是面试时候一般需要写的深克隆,而实际开发环境中,一般使用

JSON.parse(JSON.stringify(obj))

这种方式的弊端就是无法正确克隆函数、正则、日期等,但是一般开发的话只需要克隆数组、对象、基本值

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值