js对象的浅拷贝和深拷贝

js对象的浅拷贝和深拷贝,第1张

目录

一:浅拷贝

二:深拷贝的底层原理

三:给出深拷贝和浅拷贝的语法糖和区别:


一:浅拷贝

底层原理,创建一个新的对象,利用遍历的方式把原来对象的键对值给新对象,代码如下

​
       let obj = {
            name: "张三",
            sex: "男",
            age: 18,
            testArr: [1, 2, 3],
            msg: {
                adress: "中国山东蓝翔计数学院",
                hobbit: "吃小火锅"
            },
            testFunction: function() {
                console.log("给你两拳")
            }
        }
            //创建一个新对象
          let copyObj = {}
           //遍历原有对象并把它的键对值复制给新对象
          for (let k in obj) {
            copyObj[k] = obj[k]        
          }
            console.log(copyObj )
​            console.log(copyObj.msg===obj.msg)

最后我们来检验一下代码执行结果:

       可以看到我们生成了一个新的对象,内容跟原有对象一样。但是当对象里存在复杂数据类型的时候,由于js复杂数据类型的存储机制,实际上新生成的对象和原来对象属性名里存储的是同一个地址,这会导致我们修改了其中一个的时候另外一个也会改变,我们对这句话做出检验。

     

        copyObj.msg.name = "李四"
        console.log(copyObj.msg.name, obj.msg.name)

再次来看代码执行结果

                      

        我们只修改了一个对象储存的信息,另外一个对象里存储的信息也被改变了,这不符合我们的使用习惯,所以有了深拷贝。

二:深拷贝的底层原理

      1.我们构造一个遍历对象用的函数,它对对象属性存的数据类型进行判断。

      2.如果该数据类型是简单数据类型,就通过键对值复制的方法储存到新对象里

      3.如果该数据类型是复杂数据类型,就创建一个值为空的对应的复杂数据类型数据,调用定义好的函数对这一项单独进行遍历,把键对值得集合保存在这个空的数据里,整体储存在上一层对象里。

代码如下:

​
​
     function deepCopy(oldObj, newObj) {
            for (let k in oldObj) {
                if (oldObj[k] instanceof Object == false) {
                    newObj[k] = oldObj[k]
                } else if (oldObj[k] instanceof Array) {
                      //对数组进行深拷贝
                    newObj[k] = []
                    oldObj[k].forEach(function(value) {
                        newObj[k].push(value)
                    })
                 } else if (oldObj[k] instanceof Object && oldObj[k] instanceofFunction== false) { 
                   //对对象里的对象进行深拷贝
                    newObj[k] = {}
                    deepCopy(oldObj[k], newObj[k])
                }
            }
        }
        let newObj = {}
        deepCopy(obj, newObj)
            //打印函数的执行结果,并对对象里储存的复杂数据类型是否相等做出判断
        console.log(newObj)
        console.log(obj.msg === newObj.msg)

​

​

代码执行结果如下

  可以看到深拷贝出来的复杂数据类型的地址是不同的,当我们改变了其中一个对象的信息的时候,另外一个对象的信息不会改变。

下面做出验证: 执行如下代码:

        newObj.msg.adress = "上海市"
        console.log(newObj.msg.adress, obj.msg.adress)

结果如下: 

         

4.方法的访问可以通过call()或者bind()改变原有方法的this指向来进行访问

三:给出深拷贝和浅拷贝的语法糖和区别:

        

方法类型个人建议
Object.assign()浅拷贝
通过 JSON.parse(JSON.stringify(oldObj))简化版的深拷贝     复杂数据类型在转化的过程中会造成信息丢失。
自定义函数进行迭代拷贝深拷贝推荐

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1296309.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存