美文网首页步步为营之JavaScript
JS-对象拷贝-深拷贝&浅拷贝

JS-对象拷贝-深拷贝&浅拷贝

作者: 刘淘 | 来源:发表于2020-06-18 23:50 被阅读0次

    前置知识:
    JavaScript中数据类型分为基本数据类型(number string boolean null undefined symbol )、引用数据类型(object)。
    基本数据类型的拷贝是值拷贝,全部都是深拷贝;只有引用类型才分深拷贝、浅拷贝。

    个人的理解:
    为什么递归遍历重新赋值一下就可以达到深拷贝了呢?
    因为将数组值遍历一下,就相当于是基本数据类型拷贝了呀。

    • 可使用for循环 ...展开语法 Object.assign() 进行对象浅拷贝
    • 可使用递归算法 ,JSON.parse(JSON.stringify()) 进行对象深拷贝(对象成员包含子对象以及数组)
    //for循环进行浅拷贝
    
    const resFor={}
    for(const key in user){
        resFor[key]=user[key]
    }
    //console.log(JSON.stringify(resFor,null,2))
    resFor.name='xxx'
    resFor.arry=resFor.arry.join('=')
    //console.log(user.name)
    console.log(JSON.stringify(user),JSON.stringify(resFor))
    //打印出结果 发现user的name并未改变,不是说浅拷贝只拷贝引用呢 一个变化都变化嘛
    //再好好想一下,深浅拷贝都是相对于引用数据类型来说的,对于基本数据类型默认就是深拷贝
    //对arry进行push操作的时候,发现拷贝对象变化了,原对象也变化了,变异方法+引用类型+浅拷贝
    //当前user对象的属性都是基本数据类型,所以for循环就深拷贝了
    
    
    image.png
    const user={colors:[1,2]}
    const resExpand={ ...user }
    //使用扩展运算符进行浅拷贝
    resExpand.colors=resExpand.colors.join(',') //数组非变异方法操作
    console.log(JSON.stringify(user),'浅拷贝出来的数组:'+JSON.stringify(resExpand)) 
    //打印结果:浅拷贝出来的数组变了,原对象数组并未改变
    
    const user2={colors:[1,2]}
    const resExpand2={ ...user2 }
    resExpand2.colors.push(666) //数组变异方法操作
    console.log(JSON.stringify(user2),'浅拷贝出来的数组:'+JSON.stringify(resExpand2)) 
    //打印结果:浅拷贝出来的数组变了,原对象数组也改变
    
    //resExpand={...user}
    //数组转成字符串 join 或者直接toString()
    //join不是变异方法 所以没有影响到原对象
    /**日常将表单数据,传给接口之前,会将表单数据通过Object.assign拷贝一份作为submitFormData,然后处理submitFormData中的数组转成字符串。
    *之前在网上看到说Object.assign是浅拷贝的时候我还在疑惑,为什么是浅拷贝原表单的数组没有变化呢,现在明白了,数组转字符串这个操作不是数组变异方法,
    * 对数组进行变异方法操作 触发深拷贝,对数组进行非变异方法操作不会触发深拷贝
    */
    
    const user = { name: 'xiamu', colors: [1, 2] }
    //使用Object.assign()进行浅拷贝
    const resAssign=Object.assign({},user,{name:'xiaomuu'},{colors:[1,2]})
    //JSON.parse(JSON.Stringify())深拷贝对比
    //const resAssign = JSON.parse(JSON.stringify(user))
    resAssign.colors.push(44)
    console.log(JSON.stringify(user),JSON.stringify(resAssign))
    

    通过递归进行深拷贝

    const user = { name: 'xiamu', colors: ["red", "green"] }
    
    //通过递归进行深拷贝
    function deepCloneByRecursive(obj) {
        const res = obj instanceof Array ? [] : {}
        for (const [key, val] of Object.entries(obj)) {
            res[key] = typeof val === 'object' ? deepCloneByRecursive(val) : val
        }
        return res
    }
    
    const copyObj=deepCloneByRecursive(user)
    
    copyObj.colors.push('black')
    console.log(`原对象数据${JSON.stringify(user)}  
    拷贝后的数据${JSON.stringify(copyObj)}`)
    
    image.png

    相关文章

      网友评论

        本文标题:JS-对象拷贝-深拷贝&浅拷贝

        本文链接:https://www.haomeiwen.com/subject/vgepxktx.html