js中的 赋值 浅拷贝 和 深拷贝 详细解读

news2024/9/20 19:14:36

js数据类型主要分基本数据类型和引用数据类型。前者包括Number,String等,后者主要是Object,因此以下会针对不同的数据类型来分析,需要的朋友可以参考一下

基本数据类型(Primary Data Types):

  • String(字符串)

  • Number(数字)

  • Boolean(布尔值)

  • Null(空值)

  • Undefined(未定义)

  • Symbol(符号,ES6 新增)

  • BigInt(大整数,ES2020 新增)

引用数据类型(Reference Data Types):

  • Object(对象)

  • Array(数组)

  • Function(函数)

  • Date(日期)

  • RegExp(正则表达式)

  • Map(映射)

  • Set(集合)

  • WeakMap(弱映射)

  • WeakSet(弱集合)

前言:在学习下面文章前我们简单了解一下的内存的知识,以下先简要提一下

1、js内存

js内存,或者说大部分语言的内存都分为栈和堆。基本数据类型的变量值分配在栈上,引用数据类型的变量值分配在堆上,栈中只是存储具体堆中对象的地址。

2、赋值

对于基本数据类型,赋值操作是拷贝,即新旧变量不会相互影响。

  let a = 1
  let b = a
  b = 2
  console.log(a) // 1
  console.log(b) // 2

对于引用数据类型,赋值操作只是在栈中新增一个指向堆中对象的变量,即复制引用地址。新旧变量之间会互相影响,即在新变量上改变对象值,旧变量对应值也会改变。

  let a = {
    name: "mike"
  }
  let b = a
  b.name = "jack"
  console.log(a) // {name: "jack"}

3、浅拷贝

对于基本数据类型和不具有嵌套对象的数据,均是拷贝操作,新旧变量之间不会相互影响。

  let a = {
    name: "mike"
  }
  let b = {}
  b.name = a.name
  b.name = "jack"
  console.log(a) // {name: "mike"}

但是对于具有嵌套对象的数据,浅拷贝只拷贝第一层对象,深层次的值仍然是复制引用地址。

  let a = {
    name: "mike",
    language: {
      first: "english",
      second: "chinese"
    }
  }
  let b = {}
  b.name = a.name
  b.name = "jack"
  b.language = a.language
  b.language.first = "japanese"
  console.log(a) // {"name":"mike", language : {first: "japanese", second: "chinese"}}

js实现浅拷贝,思想:遍历target的每个属性,将起属性名和值赋值给新变量。

如果你明白了赋值的含义,那么在代码的第四行,当此时的target[key]的值是对象的时候,通过赋值赋予新变量,本质上是复制引用数据类型在堆中的地址,就不难理解为什么浅拷贝对于是否是嵌套对象的有不同结果了。

  function shallowCopy(target) {
    let result = {}
    for (const key in target) {
      result[key] = target[key]
    }
    return result
  }

4、深拷贝

深拷贝是完完全全的拷贝,新旧变量之间不会相互影响。

对于参数是否是对象有不同的处理方法,如果是对象,对于对象的每个属性和值赋值然后递归处理; 否则直接返回。

  function clone(target) {
    if (typeof target === "object") {
      //判断是否是数组
      let result = Array.isArray(target) ? [] : {}
      for (const key in target) {
        result[key] = clone(target[key])
      }
      return result
    }
    else {
      return target
    }
  }

到此这篇关于js中的赋值 浅拷贝和深拷贝详细的文章就介绍到这了

 **************************************************************************************************************

补充——浅拷贝和深拷贝的更加完善的函数

  // 浅拷贝
  const shallowClone = target => {
    // 基本数据类型直接返回
    if (typeof target === 'object' && target !== null) {
      // 获取target 的构造体
      const constructor = target.constructor
      // 如果构造体为以下几种类型直接返回
      if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) {
        return target
      }
      // 判断是否是一个数组
      const cloneTarget = Array.isArray(target) ? [] : {}
      for (prop in target) {
        // 只拷贝其自身的属性
        if (target.hasOwnProperty(prop)) {
          cloneTarget[prop] = target[prop]
        }
      }
      return cloneTarget
    } else {
      return target
    }
  }
  // 深拷贝
  const completeDeepClone = (target, map = new WeakMap()) => {
    // 基本数据类型,直接返回
    if (typeof target !== 'object' || target === null) {
      return target
    }
    // 函数 正则 日期 ES6新对象,执行构造题,返回新的对象
    const constructor = target.constructor
    if (/^(Function|RegExp|Date|Map|Set)$/i.test(constructor.name)) {
      return new constructor(target)
    }
    // map标记每一个出现过的属性,避免循环引用
    if (map.get(target)) {
      return map.get(target)
    }
    map.set(target, true)
    const cloneTarget = Array.isArray(target) ? [] : {}
    for (prop in target) {
      // 实现一个深拷贝函数通常需要递归地检查每个属性,如果属性值是对象,则递归调用自身进行拷贝;否则,直接复制该属性值。
      if (target.hasOwnProperty(prop)) {
        cloneTarget[prop] = completeDeepClone(target[prop], map)
      }
    }
    return cloneTarget
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2149795.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

--芯片测试--

目录 芯片逻辑是什么 芯片如何选型? 测试策略有什么 Alpha测试和Beta测试的区别? 主要区别 TOPS是什么 如何计算TOPS MAC单元是什么 频率的单位是什么 如何解决跨时钟域问题? 解释一下对异步电路的理解,以及如何实现同步…

【北京迅为】《STM32MP157开发板使用手册》-第四十三章 软件定时器实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐…

seL4 Capabilities(翻自官网)(一)

官网教程链接: Capability 初始化Capabilities tutorials // 先使用repo拉取一下tutorials,然后执行repo sync,所有的教程都在里面,学习某个的时候只需要改变的是 --tut 后面的参数 ./init --tut capabilities # building the tutorial exe…

电商商品详情API接口对电商跨境电商企业运营的好处

为了获取更大利益,电商商家经常需要使用价格,ERP接口系统。价格接口对电商商家有多方面的好处,主要体现在以下几个方面: 1、价格接口系统可以帮助品牌和商家实现更加科学和精准的定价策略。通过实时获取多个主流电商平台&#xf…

我与Linux的爱恋:进程优先级|进程切换

​ ​ 🔥个人主页:guoguoqiang. 🔥专栏:Linux的学习 文章目录 1.进程优先级1.什么是进程优先级?2.进程优先级的类型3.进程优先级的作用4.进程优先级的实现5.进程优先级的重要性6.查看系统进程7.修改进程优先级8.优先…

通过蓝图Blueprint完成项目拆分、模块化以及模块化后项目结构分析

1、不拆分项目之前的写法 在上一篇Flask入门和视图中我们讲解了Flask项目的一个启动流程,引入Flask、创建Flask对象,然后由路由进入在视图函数中通过模版渲染或者json系列化的方式返回页面或者数据。我们发现这些所有的操作都是在一个页面中完成的&…

信息化时代下的高标准农田灌区:变革与机遇并存

在信息化时代的浪潮中,高标准农田灌区的建设与管理正经历着前所未有的变革,这既是一个挑战重重的历程,也孕育着无限的发展机遇。随着物联网、大数据、云计算以及人工智能等先进技术的飞速发展与融合应用,传统的农田灌溉模式正在被…

【Docker】安装全流程与配置完整镜像源(可安装 nginx)

目录 一、卸载历史版本(选)二、配置 yum 源三、安装 docker四、配置 docker 镜像源加速(选、强烈建议)4.1 配置阿里镜像加速4.2 配置其他镜像源 五、启动 docker参考文章与视频 本文基于 Linux - CentOS 7 操作系统。 一、卸载历史…

PG198-jesd204-phy阅读笔记

简介 介绍 JESD204 PHY IP核实现了JESD204的物理接口,简化在发送和接收核心之间共享串行收发器信息通道。此内核一般不单独使用,只能与JESD204或JESD204C内核结合使用。 特性 根据JESD204B和JESD204C草案设计   支持1至12lane配置   JESD204 IP支持…

clousx6整点报时指令怎么写?

🏆本文收录于《全栈Bug调优(实战版)》专栏,主要记录项目实战过程中所遇到的Bug或因后果及提供真实有效的解决方案,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&am…

对称加密算法使用示例

Demo包括以下对称加密算法组合 备注:XTS仅支持AES128和AES256,不支持AES192 from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.primitives import cmac from cryptography.hazmat.primitives.…

SpringBoot 基于 Vue 的地方美食分享网站

摘要 首先,论文一开始便是清楚的论述了系统的研究内容。其次,剖析系统需求分析,弄明白“做什么”,分析包括业务分析和业务流程的分析以及用例分析,更进一步明确系统的需求。然后在明白了系统的需求基础上需要进一步地…

smardaten无代码这么牛逼?逻辑编排不用代码!

目录 前言 经典案例 ①计划编排:数据操作自动化 ②工单派工:流程变更自动化 smardaten能力解析 一、逻辑控制篇 (1)变量定义与操作 (2)数据校验与反馈 (3)动态数据获取与回填…

企业微信oauth2提示应用无法使用

问题描述: 生成oauth2之后,我a公司是服务商,我给b公司的人去点授权链接会提示这个 应用服务商还没有在企业微信为你开通接口调用许可」,导致无法使用此应用,请联系服务商开通 正文 你先要知道一件事!&…

基于SpringBoot+Vue的“课件通”中小学教学课件共享平台

作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于JavaSpringBootVueMySQL的…

后端原型设计

一:导航设计 1.1 横向导航栏 常用于浏览器对客的系统。 1.2 纵向导航栏 纵向导航左边可以进行一级菜单和二级菜单,每个二级菜单右边还可以继续再使用标签栏进行导航三级分类。 头条号和CSDN都是采用该方式。 1.3 横纵结合导航栏 横向为一级菜单&…

ConvexHull-凸包-原理-代码实现

定义:凸包是包围点云的最小凸多面体,所有点都在该多面体的内部或表面上。优点:能够精确地包围点云,并且不存在额外的空白区域。缺点:计算复杂度高,尤其是在高密度点云中,生成凸包的过程较慢。 …

前后端分离项目--下载功能

文章目录 不使用代理服务器blobblob构造函数通过FormData对象的getBlob方法创建Blob对象将Blob对象转换成UR 使用代理服务器 前后端分离项目中下载与其他接口的使用不同,一般下载不走node,不通过代理服务器,而是直接在前台发送请求&#xff0…

人工智能安全治理新篇章:《2024人工智能安全治理框架1.0版》深度解读@附20页PDF文件下载

在数字化浪潮席卷全球的今天,人工智能(AI)技术正以前所未有的速度融入我们的日常生活,从智能助手到自动驾驶,从医疗诊断到金融风控,AI的身影无处不在。然而,技术的双刃剑特性也让我们不得不面对…

3657A/B/AM/BM矢量网络分析仪

苏州新利通 3657A/B/AM/BM 矢量网络分析仪 3657系列矢量网络分析仪适用于无线通信、有线电视、教育及汽车电子等领域,可用于对滤波器、放大器、天线、电缆、有线电视分接头等射频元件的性能测量。该产品采用Windows操作系统;具有误差校准功能、时域功能…