美文网首页
Js基础知识-手动实现深拷贝

Js基础知识-手动实现深拷贝

作者: 小恐龙yaya | 来源:发表于2020-04-11 16:41 被阅读0次

    本文将手动实现引用类型的深拷贝
    关于值类型与引用类型可阅读下方文章:
    JS基础类型直通车:
    Js基础知识-变量类型
    Js基础知识-typeof运算符

    let obj1={
      name:'王',
      age:23,
      address:{
        city:'河南省郑州市'
      },
      hobby:['play','eat']
    }
    let obj2=obj1
    console.log(obj1.name) // 王
    obj2.name='李'
    console.log(obj1.name) // 李
    

    由于直接将obj1直接赋值给了obj2,此时他们的指针地址是相同的,所以当obj2改变时,obj1的值也会改变。

    如何将obj1赋值给obj2,修改obj2的值obj1得值不会改变?

    • 创建方法deepClone,将返回一个值作为方法的返回值
    /**
    * 深度克隆
    * @param {object} obj 需要克隆的对象/数组
    */
    function deepClone(obj={}){
        return  obj
    }
    
    • 检查传入的参数类型是否为引用类型,不是的话将参数直接返回
    /**
    * 深度克隆
    * @param {object} obj 需要克隆的对象/数组
    */
    function deepClone(obj={}){
      if(typeof obj!=='object'||obj==null){
        return  obj
      }
    }
    
    • 处理参数为引用类型,检查是否为数组,定义新的变量
    /**
    * 深度克隆
    * @param {object} obj 需要克隆的对象/数组
    */
    function deepClone(obj={}){
      if(typeof obj!=='object'||obj==null){
        return  obj
      }
      let result  // 将要返回的变量
      if(obj instanceof Array){
        result=[]   // 如果Obj为数组,则将返回定义为空数组
        }else{
        result={} // 如果Obj为对象,则将返回定义为空对象
      } 
    }
    
    • 遍历赋值

    会用到递归,如果不清楚可以将每一个obj的值进行打印。

    /**
    * 深度克隆
    * @param {object} obj 需要克隆的对象/数组
    */
    function deepClone(obj={}){
      if(typeof obj!=='object'||obj==null){
        return  obj
      }
      let result  // 将要返回的变量
      if(obj instanceof Array){
        result=[]   // 如果Obj为数组,则将返回定义为空数组
        }else{
        result={} // 如果Obj为对象,则将返回定义为空对象
      } 
     // forin可以用于对象和数组的遍历
        for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
           result[key]=deepClone(obj[key]) // 使用递归
        }
      }
    }
    
    • 再次声明测试
    /**
    * 深度克隆
    * @param {object} obj 需要克隆的对象/数组
    */
    function deepClone(obj={}){
      console.log(obj)
     //obj每次的值
     //王     23     {city: "河南省郑州市"}      河南省郑州市      ["play", "eat"]     play       eat
      if(typeof obj!=='object'||obj==null){
        return  obj
      }
      let result  // 将要返回的变量
      if(obj instanceof Array){
        result=[]   // 如果Obj为数组,则将返回定义为空数组
        }else{
        result={} // 如果Obj为对象,则将返回定义为空对象
      } 
     // forin可以用于对象和数组的遍历
        for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
           result[key]=deepClone(obj[key]) // 使用递归
        }
      }
      return result
    }
    let obj2=deepClone(obj1)
    obj2.name='李'
    console.log(obj1.name,obj2.name) // 王 李
    

    经过手动实现深度拷贝后就会发现,当改变obj2的值后,obj1并不会发生改变。

    上一章 : Js基础知识-typeof运算符

    相关文章

      网友评论

          本文标题:Js基础知识-手动实现深拷贝

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