JS深拷贝和浅拷贝

文章详细阐述了JavaScript中的深拷贝和浅拷贝概念,分别对应于对对象复制时的不同层次。浅拷贝仅复制对象的第一层属性,对于引用类型则拷贝内存地址,导致原对象和副本的深层修改相互影响。而深拷贝则会创建完全独立的新对象,即使属性是引用类型也会在堆内存中新开辟区域,确保修改不会影响原对象。文中提到了使用Object.assign、JSON.parse、以及递归实现深拷贝的优缺点。
摘要由CSDN通过智能技术生成

浅拷贝和深拷贝

前言:要了解深拷贝和浅拷贝首先要清楚数据的基本类型和引用类型

  • 基本类型:undefined、none、number、string、boolean、bigint、symbol

    放在栈内存中,数据不可变

  • 引用类型:Object、Array、Function

    地址:数据的映射关系来进行存储。地址放在栈内存,数据放在堆内存

进入正题,根据代码看区别

  1. 赋值:将某一个数值给一个变量的过程

    let obj = {
      name:'花开富贵',
      hobby:['花开','富贵','花开富贵']
    }
    let object = obj
    object.name = '金生水起'
    console.log(obj.name)
    console.log(object.name)
    
  2. 浅拷贝:创建一个新对象,该对象有原始对象属性值的精确拷贝。若属性是基本类型,拷贝值,若属性是引用类型,拷贝内存地址。

    let obj = {
      name:'花开富贵',
      hobby:['花开','富贵','花开富贵']
    }
    
    function shallowCopy(sourse){
      let object = {}
      for(let i in sourse){
        if(sourse.hasOwnProperty()){
          object[i] = sourse[i]
        }
      }
      return object
    }
    
    let shallowObj = shallowCopy(obj)
    shallowObj.name = '金生水起'
    
    console.log(shallowObj.name) //金生水起
    console.log(obj.name)        //花开富贵
    
    

    注:

    hasOwnProperty是Object.prototype的一个方法
    他能判断一个对象是否包含自定义属性而不是原型链上的属性
    hasOwnProperty 是 JavaScript 中唯一一个处理属性但是不查找原型链的函数

  3. 深拷贝:创建一个新对象,该对象是将原始对象从内存中完整的拷贝出来,从堆内存中开辟新的区域存放新对象,彼此独立。若属性是基本类型,拷贝值。若属性是引用类型,拷贝的不是内存地址,而是在堆内存中开辟一个新的区域存放新对象

    深拷贝的方法:

    1. Object.assign
      缺点:被嵌套的对象进行的还是浅拷贝
    let obj = {
    name:'花开富贵',
    hobby:['花开','富贵','花开富贵']
    }
    
    function deepCopy(sourse){
    return Object.assign({},obj)
    }
    
    let deepObj = deepCopy(obj)
    deepObj.hobby[0] = '富贵'
    
    console.log(deepObj.hobby[0]) //富贵
    console.log(obj.hobby[0])     //富贵
    
    1. JSON
      缺点:不可以拷贝 undefined , function, RegExp,Data 等等类型的
    let obj = {
    name:'花开富贵',
    hobby:['花开','富贵','花开富贵']
    }
    
    let deepObj = JSON.parse(JSON.stringify(obj))
    deepObj.hobby[0] = '富贵'
    
    console.log(deepObj.hobby[0]) //富贵
    console.log(obj.hobby[0])     //花开
    
    1. jquery的extand

    2. 递归

    let obj = {
              name:'花开富贵',
              hobby:['花开','富贵','花开富贵']
          }
          
          function deepCopy(sourse){
              if(sourse === null) return sourse
              if(sourse instanceof Date) return new Date()
              if(sourse instanceof RegExp) return new RegExp(sourse)
              if(typeof sourse !=="object") return sourse
    
              let obj = Array.isArray(sourse)?[]:{}
              for(let i in sourse){
                  if(sourse.hasOwnProperty(i)){
                      obj[i] = deepCopy(sourse[i])
                  }
              }
              return obj
          }
    
          let deepObj = deepCopy(obj)
          deepObj.hobby[0] = '富贵'
    
          console.log(deepObj.hobby[0]) //富贵
          console.log(obj.hobby[0])     //花开
    

总结

深浅拷贝重点在 对象

浅拷贝:

就是只拷贝第一层

基本类型,拷贝值

引用类型拷贝内存地址。引用类型值改变,原对象就改变。

深拷贝:

就是拷贝到底层

基本类型,拷贝值

引用类型,在堆内存中开辟一个新的区域存放新对象。引用类型值改变,原对象不改变。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值