首页 > 其他分享 >前端项目中关于深拷贝和浅拷贝的遇见

前端项目中关于深拷贝和浅拷贝的遇见

时间:2022-08-19 21:13:33浏览次数:45  
标签:target keys 前端 Object source let 遇见 拷贝

项目初次接触:获取的数据赋值给变量,经过开关按钮切换后,数据变了,发现原来只是浅拷贝了。

深拷贝:也叫 值拷贝

浅拷贝: 也叫 引用拷贝

浅拷贝就只是复制对象的引用

  原始类型 Undefined,Null,Boolean, Number,String 是存入堆中,直接引用

  Object, Array则是存入栈中,只用一个指针来引用值,如果拷贝后的对象发生变化,原对象也会发生变化

 

  对象数据存放在堆内存中,对象变量存放在栈内存中,对象变量通过引用数据的堆地址实现对象访问

 

js 中的深拷贝(值拷贝)

  基本数据类型:String, Number, Boolean, Undefined, Null ,在赋值的过程中都是值拷贝

js 中的浅拷贝(引用拷贝)

  js 中的对象数据类型: Object , Array, Function, Map, Set ,在赋值过程中都是引用拷贝

将浅拷贝转换成深拷贝

  Array 的深拷贝

    通过 slice 方法

      slice() 方法操作数组时,不会对原数组有影响,会产出一个新的数组

        slice() 方法选择从给定的start参数开始的元素,并在给定的end 参数处结束,但不包括。

    通过 concat 方法

      数组的 concat() 方法,能够连接两个数组,同样不会改变原来的数组。用一个空数组连接另一个数组,即可实现深拷贝

        let arr1 = [1,2,3];

        let arr 2 = [].concat(arr1)

    通过 ES6语法中 解构 ...

      ES6 语法中的结构 ... 经常在数组的深拷贝中用到

        let arr1 = [0,1,2]

        let arr2 = [...arr1]

    通过Array.forn方法

      Array.from() 方法能从一个类似数组或可迭代对象中返回一个新的数组实例。通过Array.from()方法能获取到一个数组的深拷贝

        let arr1 = [1,2,3]

        let arr2 = Array.from(arr1)

  Object的浅拷贝

    通过Object.assign()方法

      Object.assign(target,...source)

      let copyobj = Object.assign({}, sourceobj);

      针对深拷贝问题,需要使用其他办法,因为Object.assign()只复制属性值

    通过展开语法实现浅拷贝

      let copyObj = {...target}

    通过Object.create() 实现浅拷贝

      let cloneObj = Object.create(

        Object.getPrototypeof(target),

        Object.getOwnPropertyDescriptors(target))

    

   Object 深拷贝

    通过JSON转换实现深拷贝

      let copyObj = JSON.parse(JSON.stringify(target))

       也会存在一些问题: 对某些数据不支持:

          如Date类型会被转为字符串类型,

          Undefined和RegExp类型丢失等问题。

          无法拷贝存在循环引用的对象。

          拷贝自身可枚举字符串属性,原型链丢失。

          属性特性丢失。 性能较差。

    手动实现深拷贝

     

function deepClone(target) {
    if (!(target instanceof Object) || 'isClone' in target)
        return target;
    
	let clone = null;
    if (target instanceof Date)
        clone = new target.constructor(); 
    else if(Array.isArray(target))
        clone = [];
    else
        clone = new target.constructor();
	let keys = Reflect.ownKeys(target);
    for (let key of keys) {
        if (Object.prototype.hasOwnProperty.call(target, key)) {
            target['isClone'] = null;
            clone[key] = deepClone(target[key]);
            delete target['isClone'];
        }
    }
    return clone;
}

  

方法二:项目中

export function deepClone(source) {
  if (!source && typeof source !== 'object') {
    throw new Error('error arguments', 'deepClone')
  }
  const targetObj = source.constructor === Array ? [] : {}
  Object.keys(source).forEach(keys => {
    if (source[keys] && typeof source[keys] === 'object') {
      targetObj[keys] = deepClone(source[keys])
    } else {
      targetObj[keys] = source[keys]
    }
  })
  return targetObj
}

 

参考:https://juejin.cn/post/6872765382898221064#heading-8

标签:target,keys,前端,Object,source,let,遇见,拷贝
From: https://www.cnblogs.com/chuanmin/p/16603313.html

相关文章

  • 深浅拷贝
    Python的赋值语句不复制对象,而是创建目标和对象的绑定关系。>>>a=1>>>id(a)140731276990112>>>b=a>>>id(b)140731276990112上面的第行代码将值1的地址绑......
  • 练习3:深浅拷贝实现
    Object.assign原理及其实现MDN:主要是将所有可枚举属性的值从一个或多个源对象复制到目标对象,同时返回目标对象。//第一步leta={name:"advanced",ag......
  • 一些值得阅读的前端文章(不定期更新)
    1、面向Lighthouse编程与Vue性能优化:https://mp.weixin.qq.com/s/12Xppi2LCXddRWy9Mjw43Q 2、详解HTTPS:https://mp.weixin.qq.com/s/mpoDKIsQbNdpuBNhnvvf-g 3、Web......
  • get请求 空字符串布尔值True? 获取前端输入完整内容
    如下图须知:get请求获取的都是字符串形式;会自动给每个字符加单引号通过request.GET获取完整输入 ......
  • 【Pyhton】利用os进行文件拷贝
    【代码】#encoding=utf-8importosos.popen("copyc:\\java8\\src.zipC:\\Users\\ufo\\Desktop\\target.rar")【用途】将Java打包后的jar文件拷贝到桌面上并改名,......
  • 【nodejs】大事件后台管理项目(三)——layui前端布局
    5.文章管理5.1新建ev_articles表CREATETABLE`my_db_01`.`Untitled`(`Id`int(0)NOTNULLAUTO_INCREMENT,`title`varchar(255)NOTNULLCOMMENT'文章......
  • 小tips:怎样实现简单的前端hash与history路由方式?
    前端路由实现方式,主要有两种,分别是history和hash模式。hash模式不同路由对应的hash是不一样的,如何能够监听到URL中关于hash部分发生的变化?浏览器已经暴露给我们一个现成......
  • 前端页面串联卡片的一个思路
    串联卡片的一个思路需求描述做一行固定宽度但是数量不固定的的卡片,卡片前后通过箭头链接,箭头要处在两个卡片中间位置。问题分析首先需要一个卡片的基础组件,然后遍历数......
  • 献给前端困惑的你和我
    1.环境心态对人的影响-在fc的时候和周围同事交流不多,一方面因为工作忙,一方面因为个人比较内向,然后fc工作员工之间联系也比较少,各个员工都不太熟悉,然后每天学习时间很少,(......
  • 【性能优化】前后端使用protobuf高效传递大量数据——前端
    Protobuf简单介绍GoogleProtocolBuffer(简称Protobuf)是一种轻便高效的结构化数据存储格式,平台无关、语言无关、可扩展,可用于通讯协议和数据存储等领域。有几个优点:......