当前位置: 首页 > news >正文

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

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 = 1let b = ab = 2console.log(a) // 1console.log(b) // 2

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

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

3、浅拷贝

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

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

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

  let a = {name: "mike",language: {first: "english",second: "chinese"}}let b = {}b.name = a.nameb.name = "jack"b.language = a.languageb.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.constructorif (/^(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}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Knowledge Graph Large Language Model (KG-LLM) for Link Prediction
  • QT应用开发的C++功能框架以及实战入门开发项目场景
  • 智慧交通,智能消防系统助力高铁站安全
  • [Linux]自定义shell详解
  • SpringBoot 基于 Vue 的地方美食分享网站
  • 秦时明月6.2魔改版+GM工具+虚拟机一键端
  • 图片压缩格式自适应,真的很省流量!
  • 鸿蒙OpenHarmony【轻量系统内核通信机制(消息队列)】子系统开发
  • --芯片测试--
  • ARM架构下的多核处理器设计?
  • 百度移动刷下拉词工具:快速出下拉词的技术分析
  • 如何来写一份开题报告?
  • docker部署Stirling-PDF
  • 大模型-模型架构-主流架构
  • 数据结构应试-树和二叉树
  • 《Java编程思想》读书笔记-对象导论
  • echarts花样作死的坑
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • leetcode98. Validate Binary Search Tree
  • 阿里云应用高可用服务公测发布
  • 前端性能优化——回流与重绘
  • 栈实现走出迷宫(C++)
  • LIGO、Virgo第三轮探测告捷,同时探测到一对黑洞合并产生的引力波事件 ...
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • #laravel 通过手动安装依赖PHPExcel#
  • #pragma pack(1)
  • $L^p$ 调和函数恒为零
  • (react踩过的坑)antd 如何同时获取一个select 的value和 label值
  • (紀錄)[ASP.NET MVC][jQuery]-2 純手工打造屬於自己的 jQuery GridView (含完整程式碼下載)...
  • (利用IDEA+Maven)定制属于自己的jar包
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (幽默漫画)有个程序员老公,是怎样的体验?
  • (原)Matlab的svmtrain和svmclassify
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • (转)Sql Server 保留几位小数的两种做法
  • (转贴)用VML开发工作流设计器 UCML.NET工作流管理系统
  • (自适应手机端)行业协会机构网站模板
  • .java 9 找不到符号_java找不到符号
  • .NET core 自定义过滤器 Filter 实现webapi RestFul 统一接口数据返回格式
  • .net core开源商城系统源码,支持可视化布局小程序
  • .NET MVC之AOP
  • .Net 访问电子邮箱-LumiSoft.Net,好用
  • .net6+aspose.words导出word并转pdf
  • .Net6使用WebSocket与前端进行通信
  • .NET简谈互操作(五:基础知识之Dynamic平台调用)
  • [ vulhub漏洞复现篇 ] ECShop 2.x / 3.x SQL注入/远程执行代码漏洞 xianzhi-2017-02-82239600
  • [ 攻防演练演示篇 ] 利用通达OA 文件上传漏洞上传webshell获取主机权限
  • [Android]将私钥(.pk8)和公钥证书(.pem/.crt)合并成一个PKCS#12格式的密钥库文件
  • [bzoj1324]Exca王者之剑_最小割
  • [c#基础]DataTable的Select方法
  • [C#基础]说说lock到底锁谁?
  • [EFI]Lenovo ThinkPad X280电脑 Hackintosh 黑苹果引导文件
  • [flink]部署模式
  • [GN] Vue3快速上手1
  • [Java] 模拟Jdk 以及 CGLib 代理原理