javascript 深浅拷贝

javascript 深浅拷贝

拷贝 = 复制
内容(javascript对象)

// 如:
let obj1 = {
    name:"jack",
    age:18,
    fun:{
    swimimg:'游泳'
    }
}
// 新对象
let obj2 = {
    name:"jack",
    age:18,
    fun:{
    swimimg:'游泳'
    }
}
分类

浅拷贝(只拷贝一层对象) 深拷贝(可以拷贝嵌套对象)

拷贝的实现方式
  • 赋值式不是拷贝(let newObj = obj )
    只是给源对象重新定义了一个类名,将堆区域的地址赋给了它,两个类名都可以通过点语句修改和操作对象里定义的属性值,而不是拷贝了一个新对象。
<script>
 // 要拷贝的对象
 let obj = {
    name:"jack",
    age:18
 }
 let newObj = obj 
  consol.log("newObj",newObj ) // newObj:{name:"jack",age:18}
 </script>
  • JSON.parse(JSON.stringify(obj))(JONS是深拷贝)
    可以拷贝一个新对象,重新在堆区域里面创建了一个储存地址,在新对象里修改对象里的属性值不会影响原来的对象,并且是完全拷贝(可以拷贝嵌套的对象),但不能拷贝Function函数和值是undefind的属性
<script>
 // 要拷贝的对象
 let obj = {
    name:"jack",
    age:18say:function(){ // 该方法不能拷贝函数
       consol.log("say>>>>>")
    },
    null:undefind, // 该方法不能拷贝值为undefind的属性
    fun:{
      swimming:"游泳"
    }
 }
 /*
 * 实现方式:JSON.parse(JSON.stringify(obj))
 */
 // 拷贝obj对象
 let newObj = JSON.parse(JSON.stringify(obj))
 consol.log("拷贝后的对象newObj",newObj ) // newObj:{name:"jack",age:18,fun{swimming:"游泳"}}
</script>
  • 扩展运算符(展开运算符是浅拷贝) {. . .obj} <==> object.assign(obj)
    只能拷贝一层,不能拷贝嵌套对象,可以拷贝函数function和值是undefind的属性
// 要拷贝的对象
 let obj = {
    name:"jack",
    age:18say:function(){ 
       consol.log("say>>>>>")
    },
    null:undefind,
    
    fun:{ // 不能拷贝嵌套对象
      swimming:"游泳"
    }
 }
 /*
 * 实现方式:{...obj}
 */
 // 拷贝obj对象
 let newObj = {...obj}
 consol.log("拷贝后的对象newObj",newObj ) // newObj:{name:"jack",age:18,say:function(){ consol.log("say>>>>>")}, null:undefind}
</script>
  • 递归拷贝
    1.有嵌套对象
    2.有函数function和undefind
<script>
// 深拷贝 递归实现
 const cloneDeep = data => {
      const newData = Array.isArray(data) ? [] : {}
      for (let key in data) {
          if(data[key] && typeof data[key] === 'object') {
          nawData[key] = cloneDeep(data[key])
          } else {
            newData[key] = data[key]
          }
      }
      return newData  
 }
</script>
  • 优化:根据实际情况完成不同的拷贝,先封装两个判断条件
    类型判断:object.prototype.toString.coll(num) [object String] [object Object ] [object Array] [object Function]

// 判断对象属性值是否有对象,就是对象是否有嵌套对象
const isObjectValue = data => {
    for (let key in data) {
       if(data[key] && typeof data[key] === 'object') {
          if(object.prototype.toString.call(data[key]) !== '[object function]'){
             return true
          }
       }
    }
}

// 递归判断数据类型
const isFunctionUndefined = data=> {
   for (let key in data) {
      if(data[key] === undefined) {
         return true
      } else if (data[key] && object.prototype.toString.coll(data[key]) === '[object Function]'){
         return true // Function
      } else if (data[key] && typeof data[key] === 'object') {
         isFunctionUndefined(data[key])
      }
   }
}

// 使用递归方法拷贝对象
const cloneDeepObj = obj => {
   if(obj === undefined) {
      throm new TypeError('param is not undefined')
   }
   // 判断拷贝对象只有一层及属性值都不是对象,使用Object.assign() === 扩展运输符[...]
   if(!isObjectValue(obj)) {
      return {...obj}
   }
   // 判断类型,如果不是Function或undefined使用JSON方式
   if(!isFunctionUndefined(obj)) {
      return JSON.parse(JSON.stringify(obj))
   }
   return cloneDeep(obj)
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值