对前端深浅拷贝的思考

综述:一个简单的问题,其实有些细节需要好好总结下

1.浅拷贝的方法

  • es6  扩展运算符...

用扩展运算符对数组或者对象进行拷贝时,只能扩展和深拷贝第一层的值,对于第二层极其以后的值,扩展运算符将不能对其进行打散扩展,也不能对其进行深拷贝,即拷贝后和拷贝前第二层中的对象或者数组仍然引用的是同一个地址,其中一方改变,另一方也跟着改变,这里就属于浅拷贝。

  • Object.assign() 只能实现对象第一层级的浅拷贝
  • 直接使用等号只能实现基本数据类型的浅拷贝

2.深拷贝的几种方式

  • JSON.parse(JSON.stringify(obj)),当obj中存在new Date 时,会转成一个字符串时间, 函数对象时,也会转成一个新的字符串,  正则表达式时也会转成字符串,会存在bug。
  • 使用lodash库的deepClone方法
  • 自己写一个深拷贝方法,对1中说明的特殊情况进行转换
function deepClone(obj){
        if(obj===null) return obj;
        if(typeof obj!=='object') return obj;
        /* 重新new是为了让他做一个复制操作,而不是原来的值返回,没有达到深拷贝的目的 */
        if(obj instanceof RegExp){
            return new RegExp(obj);
        }
        /* 重新new是为了让他做一个复制操作,而不是原来的值返回,没有达到深拷贝的目的 */
        if(obj instanceof Date){
            return new Date(obj);
        }
        // 这里的newObj不使用{},是为了保证克隆的结果和之前的保持相同的所属类,比如传进来的
        let newObj =new obj.constructor()
        for(let key in obj){
            //hasOwnProperty表示是否有自己的属性。这个方法会查找一个对象是否有某个属性,但是不会去查找它的原型链
            if(obj.hasOwnProperty(key)){
                console.log(obj[key],key,'key')
                newObj[key] = deepClone(obj[key])
            }
        }
        return newObj;
    }
    const testObj = {a:1,b:{c:new Date(),d: function(){console.log(6666)}}}
    console.log(deepClone(testObj))
    console.log(JSON.parse(JSON.stringify(testObj)))

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值