js如何实现深度克隆,带你理解掌握浅拷贝和深拷贝......

   日期:2020-05-24     浏览:111    评论:0    
核心提示:1.首先我们先来理解一下什么是浅拷贝,什么是深拷贝吧浅拷贝(对象/数组) 特点: - 拷贝的是引用(即地址值),修改拷贝以后的数据,会影响原数据 - 拷贝数据的方法(浅拷贝) 1. 直接赋值给一个变量 //浅拷贝 2. Object.assign() //浅拷贝 3. Array.prototype.concat() //浅拷贝 4. Array.prototype.slice() //浅拷贝 - 下面我们用代码来辅助理解jso

1.首先我们先来理解一下什么是浅拷贝,什么是深拷贝吧

浅拷贝(对象/数组) 特点:
  -  拷贝的是引用(即地址值),修改拷贝以后的数据,会影响原数据
  -  拷贝数据的方法(浅拷贝)
      1. 直接赋值给一个变量   //浅拷贝
      2. Object.assign()    //浅拷贝
      3. Array.prototype.concat()  //浅拷贝
      4. Array.prototype.slice()   //浅拷贝
  -  下面我们用代码来辅助理解
// 1. 直接赋值给一个变量 //浅拷贝
         let obj1 = {name:'coderlyk',age:31}
         let obj2 = obj1
         
         obj2.name = "newname"//obj1和obj2的name属性值都改变了,浅拷贝
         console.log(obj1,obj2)//两个对象都返回{name:'newname',age:31}
// 2. Object.assign() //浅拷贝
          let obj1 = {name:'kobe',age:29}
          let obj2 = Object.assign(obj11)
          
          obj2.name = "wade"//obj1和obj2的name属性值都改变了,浅拷贝
          console.log(obj1,obj2)//两个对象都返回 {name:'wade',age:29}
// 3. Array.prototype.concat() //浅拷贝
          let arr1 = [1,2,true,{name:'TT',age:26}]
          let testArr = [3,4]
          let arr2 = arr1.concat(testArr)
          
          console.log(arr2)
          arr2[1] = "a"//只改变了arr2
          arr2[3].name="james"//arr1[3]和arr2[3]的name属性值都改变了,浅拷贝
          console.log(arr1,arr2)
// 4. Array.prototype.slice() //浅拷贝
          let arr1 = [3,8,false,{name:'冷嘉琪',age:18}]
          let arr2 = arr2.slice()
          
          arr2[3].name = '大帅哥'//arr1[3]和arr2[3]的name属性值都改变了,浅拷贝
          console.log(arr1,arr2)

深拷贝(深度克隆)特点:
  -  拷贝后,生成一块新的内存来存放拷贝的数据,修改拷贝以后的数据,不会影响原数据
  -   拷贝数据的方法(深拷贝)
       1.JSON.parse(JSON.stringify(arr/obj))  //深拷贝(深度克隆),
          注意:拷贝的数据里不能有函数,不能处理
  -  下面我们用代码来辅助理解
// 5. JSON.parse(JSON.stringify(arr/obj)),深拷贝(深度克隆),拷贝的数据里不能有函数,处理不了
         let arr1 = [3,8,false,{name:'oldname',age:20},function fun(){console.log('fun')}]
         let arr2 = JSON.parse(JSON.stringify(arr1))
         //先通过JSON.stringify方法将arr1变成JSON字符串,再通过方法JSON.parse将JSON字符串转成数组,从而实现拷贝
         
         arr2[3].name = 'newname'//arr2[3]的name属性值改变了,arr1[3]的name属性值没变,深拷贝
         console.log(arr1)//(5) [3, 8, false, {…}, ƒ] 
         console.log(arr2)//(5) [3, 8, false, {…}, null] //函数拷贝过来变成了null 

2.如何实现深度克隆

2.1 了解如何判断数据类型,并将判断之后的数据类型的相应字符串提取出来,方便我们实现深度克隆时进行判断

  
   let n = null
   console.log(typeof n)//object

   let result = Symbol('lyk')
   console.log(Object.prototype.toString.call(result))// [object Symbol]
   console.log(typeof Object.prototype.toString.call(result))//string -》说明返回的[object Symbol] 是一个字符串
   //提取判断后数据类型字符串
   console.log(Object.prototype.toString.call(result).slice(8,-1))//Symbol

2.2 将我们深度克隆的全部代码逻辑奉上

// 1. 定义检查数据类型的功能函数
    function checkedType(target){
        return Object.prototype.toString.call(target).slice(8,-1)//如 [Object Array] 我们这样截取的就是Array
    }
// 2.实现深度克隆 ---> 对象/数组 
    function clone(target){
        // 判断拷贝的数据类型
        // 初始化变量result 成为最终克隆的数据
       
        let result, targetType = checkedType(target)

        if(targetType === 'Object'){
            result = {}
        }else if (targetType === 'Array') {
            result = []
        }else{
            return target
        }

    // 遍历目标数据
      for(let i in target){
        // 获取遍历数据的每一项值
        let value = target[i]
        // 判断目标结构里的每一个值是否存在对象/数组
        if(checkedType(value) === 'Object' || checkedType(value) === 'Array'){// 对象/ 数组里嵌套了对象/数组
             //继续遍历获取到的value值
               result[i] = clone(value)//递归
           }else {//获取到的value值是基本的数据类型或者是函数
               result[i] = value
           }
      }
      return result;
    }
    let fun = function(){
        console.log('我是fun函数')
    }
    let setArr = [1,5,true,{name:'boss',age:40},fun]
    let setNew = clone(setArr)
       setNew[3].name = "大boss"
       console.log(setArr,setNew)
       setNew[4]()
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服